http://oss.timedia.co.jp/index.fcgi/kahua-web/show/ossz/oneline/2006-04-17
出題され
http://oss.timedia.co.jp/index.fcgi/kahua-web/show/ossz/oneline/2006-04-18
で答えが出ているが、無限大を使っているのが不満であった。それに、計算誤差で負ける。
計算誤差で負けると言えば、私が先日書いた id:Nabetani:20060418:p1 も計算誤差で負ける。
というわけで。
f(f(x))==-x となり、無限大になったり計算誤差で負けたりしないものを haskell, ruby, C で書いてみた。
まずは haskell 版:
f x | x==0.0 = 0.0
| ((e+2048) `rem` 2)==0 = encodeFloat n (e+1)
| otherwise = - encodeFloat n (e-1)
where
(n,e) = decodeFloat x次は C 版
double f( double d )
{
if ( d==0 ){
return 0;
} else {
int e;
double n = frexp( d, &e );
return ( e+2048 )%2==0
? ldexp( n, e-1 )
: ldexp( -n, e+1 )
;
}
}最後に ruby 版
def f( d )
if d==0
0;
else
n, e = Math.frexp( d )
s = ( e+2048 )%2==0
Math.ldexp( s ? n : -n, e + ( s ? -1 : 1 ) )
end
end見ての通り、全部一緒。
浮動小数点の実装に触れているので若干邪悪な感じではあるが、そういうもんだとも思う。
書いていて。haskell の where が便利だと思った。
#写真と本文は関係ありません