かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Ruby Float(浮動小数点数)にはまる。

ルビーオンレールズできなくて許されるのは小学生までだよねー。クスクス。と言うことになりそうなので、

初めてのRuby

初めてのRuby

↑ でRubyを習得しようと勉強中です。
無駄に前振りが長かったですが、今回はFloat型の誤差とかにハマりましたのメモです。

返される桁数問題

特に割り算なのですが、Rubyは整数と整数で割り算をすると整数で返ってくるのに戸惑いました。
例えば「3÷2は?」って言われたら、答えは「1.5」を思い浮かべると思います。
個人的に慣れてしまっていたjavascriptで出力してみると1.5が返っていました。

console.log( 3 / 2 )  // => 1.5

で、同じ感覚でRubyで書くと

a = 3 / 2
p a # => 1

「1」になります。Integer型どうしの計算はInteger型で返ってきます。
「1.5」を得るには片方をFloat型に変換してあげでばOKです。

a = 3.to_f / 2
p a # => 1.5

mathnというライブラリを使用すると、計算式.to_fの形で書けるようです。

require "mathn"
a = 3 / 2
p a # => (3/2)

a = (3 / 2).to_f
p a # => 1.5

負の数の割り算

使いドコロがぱっと思いつかないです。
Integer型どうしで負の数の割り算をすると割り切れない計算の場合、結果がマイナス方向に1大きくなる問題。
先の例と同じ感じで「-3÷2」のパターン。javascriptでは「-1.5」になりました。

console.log( -3 / 2 )  // => -1.5

RubyだとInteger型どうしなので、Integer型になるから「-1」かな。と思っていたのですが、、、

a = -3 / 2
p a # => -2

「-2」です。 -4 ÷ 3 = 1.3333....でも

a = -4 / 3
p a # => -2

「-2」になるので、小数点以下があるとInteger型どうしの場合、マイナス方向に切り上られる仕様のようです。
この仕様を覚えていないと戸惑いそうです。

浮動小数点数の誤差

例えば消費税の計算とか。

p 225 * 1.08 # => 243.00000000000003

Floatクラスのオブジェクトは内部的に2進数にて表現される。
2進数で表現した場合に無限小数となる数の演算は全て、浮動小数点誤差が発生する可能性がある。「2進数で表現した場合に有限小数となる」とは、既約数で表現した場合の分母に2以外の素因数がない事である。

浮動小数点誤差対策 - DoRuby!

javascript

console.log( 225 * 1.08 ) // => 243.00000000000003

Chrome(48.0.2564.116)のコンソールで確認したらjavascriptでもなってましたw
不用意に繰り上げみたいなことしてたら予期しない予期しない数字とかが出てしまうので、浮動小数点数は誤差が発生するものとして気をつけましょうということですね。

まとめ

たんにゆるふわ言語javascriptから覚えてしまったのが良くなかったのか、元々数Aで挫折してる事もあって数学的な事はサッパリダメなので結構戸惑うことが多いです。

後、この勉強している「初めてのRuby」って本なのですが何となくRubyやルビーオンレールズで何かが作れている状態で、もっとキチンとRubyの言語仕様を知りたい!って人向けな気がしてきています。とりあえずRubyで何か作ってみたいから勉強しようかな―って感じだったので、延々言語仕様の細かい部分の説明なのでちょっぴり苦行感が出てきていますw (キッチリ派にはとても良い本だとは思うのですが)

という訳で、

作りながら学ぶRuby入門 第2版

作りながら学ぶRuby入門 第2版

少し古い本ですが、サクッと達成感と成功経験が得られそうだったのでモチベーションを保つために買いました。成功経験は大事ですぞ!!
初めてのKindleでしたが、技術書は場所とるしデュアルモニターだと電子書籍のほうが便利デスね!もっと早く気づくべきだった...


[参考]

プログラミング言語 Ruby

プログラミング言語 Ruby