floor() の結果が正確に表現できない場合、d の値は何になると思いますか? 確かに、変数に浮動小数点数の表現がある場合、定義により、それは正確に表現可能ですよね? あなたはdで表現を持っています...
(さらに、Mehrdad の答えは 32 ビットの int に対して正しいです。64 ビットの doubleと64 ビットの int を使用するコンパイラでは、もちろんさらに多くの問題が発生します...)
編集:おそらく、「floor() の理論上の結果、つまり、引数以下の最大の整数値は、int として表現できない可能性がある」という意味でした。確かにそうですね。int が 32 ビットのシステムでこれを示す簡単な方法:
int max = 0x7fffffff;
double number = max;
number += 10.0;
double f = floor(number);
int oops = (int) f;
浮動小数点から整数への変換がオーバーフローしたときに C が何をするかは覚えていませんが、ここで起こります。
編集: 他にも考慮すべき興味深い状況があります。C# のコードと結果を次に示します。少なくともC でも同様のことが起こると思います。C# では、double
は 64 ビットと定義されており、long
.
using System;
class Test
{
static void Main()
{
FloorSameInteger(long.MaxValue/2);
FloorSameInteger(long.MaxValue-2);
}
static void FloorSameInteger(long original)
{
double convertedToDouble = original;
double flooredToDouble = Math.Floor(convertedToDouble);
long flooredToLong = (long) flooredToDouble;
Console.WriteLine("Original value: {0}", original);
Console.WriteLine("Converted to double: {0}", convertedToDouble);
Console.WriteLine("Floored (as double): {0}", flooredToDouble);
Console.WriteLine("Converted back to long: {0}", flooredToLong);
Console.WriteLine();
}
}
結果:
Original value: 4611686018427387903
Converted to double: 4.61168601842739E+18
Floored (as double): 4.61168601842739E+18
Converted back to long: 4611686018427387904
Original value: 9223372036854775805
Converted to double: 9.22337203685478E+18
Floored (as double): 9.22337203685478E+18
long に戻す: -9223372036854775808
言い換えると:
(long) floor((double) original)
と常に同じではありませんoriginal
。これは驚くべきことではありません。(NaN 値を考えると) double よりも long 値の方が多く、多くの double は整数ではないため、すべての long が正確に表現できるとは期待できません。ただし、32 ビット整数はすべてdouble として表現できます。