O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

金勘定のためのBigDecimalそしてMoney and Currency API

13.384 visualizações

Publicada em

BigDecimal for money counting / Money and Currency API

Publicada em: Tecnologia
  • Sex in your area is here: ❤❤❤ http://bit.ly/2F4cEJi ❤❤❤
       Responder 
    Tem certeza que deseja  Sim  Não
    Insira sua mensagem aqui
  • Follow the link, new dating source: ❤❤❤ http://bit.ly/2F4cEJi ❤❤❤
       Responder 
    Tem certeza que deseja  Sim  Não
    Insira sua mensagem aqui
  • (Unlimited)....ACCESS WEBSITE Over for All Ebooks ................ accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M }
       Responder 
    Tem certeza que deseja  Sim  Não
    Insira sua mensagem aqui
  • ACCESS that WEBSITE Over for All Ebooks (Unlimited) ......................................................................................................................... DOWNLOAD FULL PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... DOWNLOAD FULL EPUB Ebook here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download Full PDF EBOOK here { http://bit.ly/2m6jJ5M } ......................................................................................................................... Download EPUB Ebook here { http://bit.ly/2m6jJ5M }
       Responder 
    Tem certeza que deseja  Sim  Não
    Insira sua mensagem aqui
  • accessibility Books Library allowing access to top content, including thousands of title from favorite author, plus the ability to read or download a huge selection of books for your pc or smartphone within minutes ,Download or read Ebooks here ... ......................................................................................................................... Download FULL PDF EBOOK here { http://bit.ly/2m6jJ5M }
       Responder 
    Tem certeza que deseja  Sim  Não
    Insira sua mensagem aqui

金勘定のためのBigDecimalそしてMoney and Currency API

  1. 1. 金勘定のためのBigDecimal そしてMoney and Currency API 2015-06-11 Java女子部勉強会 ハッシュタグ: #javajo 宮川 拓
  2. 2.  @miyakawa_taku  JJUG幹事  SI屋で賃労働  オレオレJVM言語Kinkを作っています https://bitbucket.org/kink/kink  尾上部屋の里山関のファンです 自己紹介 #javajo 2/57
  3. 3. みたいな金勘定を考えます ペンキ赤 321円 × 1.3リ ッ ト ル = 417.3円 ペンキ青 432円 × 2.2リ ッ ト ル = 950.4円 ペンキ緑 543円 × 1.6リ ッ ト ル = 868.8円 小計( 端 数 切 り 捨 て ) 2,236円 消費税( 四 捨 五 入 ) 179円 合計 2,415円 テーマ: 金勘定 小数の 演算 端数 処理 #javajo 3/57
  4. 4. セッション内容 double/floatで金勘定してはいけない BigDecimalで金勘定しよう 先取りMoney and Currency API #javajo 4/57
  5. 5. double/floatは固定精度の 2進浮動小数点数型です 10進小数が正確に表せないので、 金勘定には使えません 基本的には統計・科学技術計算のための データ型です double/float 「精度」 =「有効桁数」 #javajo 5/57
  6. 6. ありがちな言い訳  キリの良い金額しか使わないし……  誤差が出るような計算しないし……  精度足りてるからdouble/floatで大丈夫! ナーンセンス! double/float #javajo 6/57
  7. 7. double/floatではダメな理由 金額の10進小数 double/float 2進の浮動小数点数型 近似値に 丸められてしまう 以下、なぜこうなるのか説明します #javajo 7/57
  8. 8. 10進小数は 各桁に10nを掛けた数の和を表します たとえば10進の12.625: そもそも10進小数とは? 1 2 . 6 2 5 × × × × × 10 (101) 1 (100) 1/10 (10-1) 1/100 (10-2) 1/1000 (10-3) #javajo 8/57
  9. 9. 同じように2進小数は 各桁に2nを掛けた数の和を表します たとえば2進の1100.101: では2進小数とは? 1 1 0 0 . 1 0 1 × × × × × × × 8 (23) 4 (22) 2 (21) 1 (20) 1/2 (2-1) 1/4 (2-2) 1/8 (2-3) #javajo 9/57
  10. 10. 10進小数→2進小数 10進小数でピッタリ表せる値を 2進小数で表そうとすると、一般に 無限に桁が続く循環小数になります 0.1 = 0.0 0011 0011 0011 0011 0011 00... 0.2 = 0. 0011 0011 0011 0011 0011 001... 0.3 = 0.0 1001 1001 1001 1001 1001 10... #javajo 10/57
  11. 11. double/floatは固定精度、 つまり有効桁数は有限です floatの32ビットの中身: double/floatの桁数は有限 01000000110010100000000000000000 符号 0:正 1:負 指数 小数点の場所 仮数 2進の桁 桁数は固定で有限 #javajo 11/57
  12. 12. #javajo10進小数→double/float 無限の桁を有限桁に押し込もうとすると 10進小数 0.3 2進小数(無限桁数) 0.01001100110011... double/float(有限桁数) 0.010011001...110011 近似値に 丸められる 12/57
  13. 13. double/floatで金勘定すると 何が起きるのでしょうか? #javajo 13/57
  14. 14. double/floatで金勘定すると... int 定価 = 1000; double 値引率 = 0.07; int 売値 = (int) (定価 * (1 - 値引率)); System.out.println(売値); 😬 #javajo ?929 14/57
  15. 15. double/floatまとめ double/floatで金勘定してはいけません 例外:  集計・サマリ  証券のリスク計算  そのほか正確な金額がいらない場合 正確な金勘定をするためには BigDecimalクラスを使いましょう #javajo 15/57
  16. 16. セッション内容 double/floatで金勘定してはいけない BigDecimalで金勘定しよう 先取りMoney and Currency API #javajo 16/57
  17. 17. BigDecimal BigDecimal: 10進浮動小数点数 10進小数が正確に表せます 金勘定に使えます #javajo 17/57
  18. 18. BigDecimalで金勘定 int 定価 = 1000; BigDecimal 値引率 = new BigDecimal("0.07"); int 売値 = BigDecimal.ONE.subtract(値引率) .multiply(BigDecimal.valueOf(定価)) .setScale(0, RoundingMode.FLOOR) .intValue(); System.out.println(売値); 930 😄 #javajo 18/57
  19. 19. BigDecimalの構成 BigDecimal: (整数値, スケール) 整数値 任意桁数の10進の桁を表す BigInteger値 スケール 小数点を右端からいくつ左に 動かすかを表すint値 1 2 3 4 5 スケール:3 整数値: 12345 #javajo 19/57
  20. 20. ?12345000 BigDecimalの例 整数値 スケール 表される値 12345 0 12345 12345 3 12.345 12345 6 0.012345 12345 -3 #javajo スケール≧0の時、 スケールは小数点以下の桁数です 20/57
  21. 21. BigDecimalの例 同じ数を表す(整数値, スケール)の 組み合わせは複数存在します 整数値 スケール 表される値 12345 3 12.345 1234500 5 12.34500 #javajo 同じ数 21/57
  22. 22. #javajoBigDecimalの生成 主にnew BigDecimal(String)や valueOf(long)で値を生成します new BigDecimal("1.23") new BigDecimal("1.2300") BigDecimal.valueOf(42L) 1.23 スケール 2 1.2300 スケール 4 42 スケール 0 22/57
  23. 23. #javajoBigDecimalの演算 演算メソッドはオブジェクトを変更せず 結果となる新しい値を返します BigDecimal x = new BigDecimal("2.34"); BigDecimal y = new BigDecimal("4.560"); println(x.add(y)); println(x.multiply(y)); 6.900 10.67040 println(x); 2.34(変わらず) 和: 積: 23/57
  24. 24. BigDecimalの演算 足し算・引き算では、大きい方の スケールに合わせて演算されます 2.34 (スケール2) 4.560 (スケール3) + 6.900 (スケール3) #javajo 24/57
  25. 25. BigDecimalの演算 掛け算では、 スケールが足し合わされます 2.34 (スケール2) 4.560 (スケール3) × 10.67040 (スケール5) #javajo 25/57
  26. 26. BigDecimalの丸め 金額の端数処理の例:  金額の小数部を四捨五入  小数点以下2桁を残して切り捨て 端数処理に使うメソッド: setScale(新しいスケール, 丸めモード) #javajo BigDecimal 丸められた数 = 元の数.setScale(2, RoundingMode.FLOOR); 例: オブジェクトは 変更されません 26/57
  27. 27. #javajoBigDecimalの丸め setScale()による丸め: 3 2 FLOOR 3.00 1.7320 2 FLOOR 1.73 1.7320 2 CEILING 1.74 元の数 スケール 丸め 結果 27/57
  28. 28. BigDecimalの丸め 丸めモード: CEILING / FLOOR 切り上げ / 切り捨て UP / DOWN 0から遠い方 / 近い方 HALF_UP 四捨五入 HALF_DOWN 五捨五超入 HALF_EVEN 最近接偶数への丸め UNNECESSARY 丸めが必要になってしまったら ArithmeticException #javajo 28/57
  29. 29. × round(MathContext) round(MathContext)メソッドは 金勘定の端数処理には使えません #javajo setScale スケール(小数点以下の桁数)を 指定して丸める round 最大精度(整数値全体の桁数)を 指定して丸める round は、演算を繰り返すときに精度が膨れ上がって メモリを食い潰さないようにするためのメソッドです 29/57
  30. 30. × round(MathContext) 例: 精度3で切り捨てる MathContext mc = new MathContext(3, RoundingMode.FLOOR); ふつう、金 勘定でこんな処理はしないはずです #javajo new BigDecimal("1.234").round(mc) new BigDecimal("56.789").round(mc) new BigDecimal("0.0001").round(mc) 1.23 56.7 0.0001 30/57
  31. 31. BigDecimalの落とし穴 #javajo 31/57
  32. 32. BigDecimalの落とし穴1 int 定価 = 1000; BigDecimal 値引率 = new BigDecimal(0.07); int 売値 = BigDecimal.ONE.subtract(値引率) .multiply(BigDecimal.valueOf(定価)) .setScale(0, RoundingMode.FLOOR) .intValue(); System.out.println(売値); 😬 double! #javajo ?929 32/57
  33. 33. BigDecimalの落とし穴1 BigDecimalの生成にdoubleを使っては なにもかも台無しです new BigDecimal(String)を使いましょう #javajo 33/57
  34. 34. BigDecimalの落とし穴1: 修正 int 定価 = 1000; BigDecimal 値引率 = new BigDecimal("0.07"); int 売値 = BigDecimal.ONE.subtract(値引率) .multiply(BigDecimal.valueOf(定価)) .setScale(0, RoundingMode.FLOOR) .intValue(); System.out.println(売値); 930 😄 文字列を 渡しましょう #javajo 34/57
  35. 35. BigDecimalの落とし穴2 BigDecimal 総資産 = new BigDecimal("100"); BigDecimal 負債 = new BigDecimal("33.3"); BigDecimal 純資産 = new BigDecimal("66.7"); System.out.println( 総資産.equals(負債.add(純資産))); 😬 スケールが 異なるequalsが 使われている #javajo ?false 35/57
  36. 36. #javajoBigDecimalの落とし穴2 スケールが違うとequalsは成立しません 33.3 + 66.7 new BigDecimal("100") 100.0 (スケール1) 100 (スケール0) ! equals 36/57
  37. 37. BigDecimalの落とし穴2 BigDecimal.equalsはスケールも 比較します スケールを気にしないときは compareToを使いましょう #javajo 37/57
  38. 38. BigDecimalの落とし穴2: 修正a BigDecimal 総資産=new BigDecimal("100.0"); BigDecimal 負債 = new BigDecimal("33.3"); BigDecimal 純資産 = new BigDecimal("66.7"); System.out.println( 総資産.equals(負債.add(純資産))); true スケールを 合わせる 😄 または... #javajo 38/57
  39. 39. BigDecimalの落とし穴2: 修正b BigDecimal 総資産=new BigDecimal("100"); BigDecimal 負債 = new BigDecimal("33.3"); BigDecimal 純資産 = new BigDecimal("66.7"); System.out.println( 総資産.compareTo(負債.add(純資産) == 0)); true 😄 compareToを 使う #javajo 39/57
  40. 40. BigDecimalまとめ  BigDecimalは整数値とスケールで 構成されます  new BigDecimal(String)で定数を 作りましょう  端数はsetScaleで丸めましょう  BigDecimal.equalsはスケールも 比較対象です #javajo 40/57
  41. 41. 追補: BigDecimalの割り算 #javajo 41/57
  42. 42. #javajo割り算 割り算はフクザツ  ゼロ除算  割り切れないことがある  結果の桁数が大きくなるかも 例: 3/64 = 0.046875 可能なら逆数を掛ける方が良いです 例: numを4で割る num.mupltiply(new BigDecimal("0.25")) 42/57
  43. 43. #javajoBigDecimalの割り算 金勘定のための割り算メソッド: divide(除数, スケール, 丸めモード)  指定したスケールで結果を戻す  割り切れない時は丸める  結果が指定したスケールに収まらない ときは丸める divideと名のつく他のメソッドは罠です 43/57
  44. 44. 例: 費用配賦 #javajo 年間の費用を12ヶ月ごとに均等割します ただし、ひと月の費用は小数点下2桁までに 切り捨てて、端数は最後の月に寄せます 年間の費用を12ヶ月ごとに均等割します ただし、ひと月の費用は小数点下2桁までに 切り捨てて、端数は最後の月に寄せます 注意! 費用がマイナスの時は?  0の方向に丸める: -0.123 → -0.12  -∞の方向に丸める: -0.123 → -0.13 ここでは-∞の方向に丸めることにします 44/57
  45. 45. 例: 費用配賦 #javajo BigDecimal 年間費用 = new BigDecimal( "49.00" ); BigDecimal 月ごと費用 = 年間費用.divide( BigDecimal.valueOf(12), 2, RoundingMode.FLOOR); BigDecimal 最終月費用 = 年間費用.subtract( 月ごと費用.multiply(BigDecimal.valueOf(11))); System.out.println(月ごと費用); System.out.println(最終月費用); 年間の費用を12ヶ月ごとに均等割します ただし、ひと月の費用は小数点下2桁までに 切り捨てて、端数は最後の月に寄せます 4.08 4.12 45/57
  46. 46. セッション内容 double/floatで金勘定してはいけない BigDecimalで金勘定しよう 先取りMoney and Currency API #javajo 46/57
  47. 47. Money and Currency API JSR 354 Money and Currency APIは、 金勘定に関するAPIです  通貨、金額、丸め、通貨換算、書式化… Java SE 9で採用予定です クレディ・スイスが主導しています #javajo 47/57
  48. 48. なぜクレディ・スイス? スイスの特殊条件が影響?  周りは全部ユーロ圏  決済用代替通貨 WIRフラン, WIRユーロが流通している  現金決済の最小単位は 5ラッペン(5/100スイスフラン)  現金以外の最小単位は1ラッペン たしかに標準APIが欲しくなりそうです #javajo 48/57
  49. 49. JSRのステータス 2012-01 JSR Review 2012-02 Expert Group組成 2013-01 Spec Lead交代 2013-03 Early Draft 2013-10 Public Review 2014-03 Public Review 2 2015-03 Proposed Final Draft 2015-05 Final Release #javajo そこそこ難産 49/57
  50. 50. 構成 API: javax.money 実装 通貨 インタフェース 金額 インタフェース 丸め インタフェース SPI SPI SPI 通貨実装の プロバイダ 金額実装の プロバイダ 丸め実装の プロバイダ 実装はAPIから独立しています(参照実装: Moneta) 複数実装を組み合わせて使うことも可能です #javajo 50/57
  51. 51. 通貨: CurrencyUnit CurrencyUnit 日本円 = Monetary .getCurrency("JPY"); 通貨コード に対応する通貨 CurrencyUnit 地域の通貨 = Monetary .getCurrency(Locale.getDefault()); ロケールに 対応する通貨 #javajo 51/57
  52. 52. 金額: MonetaryAmount Monetaが提供する金額実装:  Money: 任意スケールの金額  FastMoney: 固定スケール(5)の金額  RoundedMoney: 演算ごとに丸める金額 Money 定価 = Money.of(1000, 日本円); System.out.println(定価); #javajo JPY 1000 52/57
  53. 53. 丸め: MonetaryRounding MonetaryRounding 整数に切捨 = Monetary .getRounding(RoundingQueryBuilder.of() .setScale(0) .set(RoundingMode.FLOOR) .build()); Money 売上 = Money.of( new BigDecimal("42.3"), "JPY"); Money 請求額 = 売上.with(整数に切捨); System.out.println(請求額); 結果のスケール 丸め方 #javajo JPY 42 53/57
  54. 54. 通貨換算: CurrencyConversion CurrencyConversion toUSD = MonetaryConversions .getExchangeRateProvider() .getCurrencyConversion(米ドル); Money 金額JPY = Money.of(42, 日本円); Money 金額USD = 金額JPY.with(toUSD); System.out.println(金額USD); 米ドルへの換算 Moneta の換算レートプロバイダは ECB/IMFのオンラインの 換算表を使います 通常、自前で換算レートプロバイダを実装するべきでしょう #javajo USD 0.3509... 54/57
  55. 55. Money and Currency APIまとめ 結構な重量級APIです つかいでのありそうなシステム  扱う通貨が可変  複数通貨間の換算を行う 関連情報へのリンク集: https://java.net/projects/jjug/pages/Adopt-a-JSR-JavaSE9 #javajo 55/57
  56. 56. セッション内容 double/floatで金勘定してはいけない BigDecimalで金勘定しよう 先取りMoney and Currency API #javajo 56/57
  57. 57. #javajo改版履歴 2015-04-11 JJUG CCC 2015 Spring 2015-06-11 Java 女 子 部 勉 強 会 「 数 値 型 お さ ら い & 金 勘 定 こ と は じ め ( BigDecimal 入 門 、 Money and Currency API 紹 介 ) 」 • BigDecimal の 割 り 算 を 追 補 • JSR-354 の 仕 様 変 更 に 追 随 • JSR-354 が Final Release さ れ た こ と を 反 映 2015-06-14 微 修 正 57/57

×