Конечно, это можно сделать программно, для любых двух чисел с плавающей запятой вообще. «Лексикографический индекс» - это упорядоченный индекс числа с плавающей запятой, доступный, среди прочего, потому что IEEE 754 был разработан таким образом, чтобы его было легко производить.
Основное правило для любых двух чисел с плавающей запятой, если (float1 > float2)
, то (lexIndex1 > lexIndex2)
.
Таким образом, вычисление числа чисел IEEE 754 между ними является вопросом вычитания лексикографических индексов двух чисел:
public class FloatUtil
{
public static uint ToLexicographicIndex(float value)
{
//transfer bits to an int variable
int signed32 = BitConverter.ToInt32(BitConverter.GetBytes(value), 0);
uint unsigned32 = (uint)signed32;
//(0x80000000 - unsigned32) returns
//appropriate index for negative numbers
return (signed32 >= 0)
? unsigned32
: 0x80000000 - unsigned32;
}
public static uint NumbersBetween(float value1, float value2)
{
if (float.IsNaN(value1) || float.IsInfinity(value1))
{
throw new ArgumentException("value1");
}
if (float.IsNaN(value2) || float.IsInfinity(value2))
{
throw new ArgumentException("value2");
}
uint li1 = ToLexicographicIndex(value1);
uint li2 = ToLexicographicIndex(value2);
//make sure return is positive
return value1 >= value2 ? li1 - li2 : li2 - li1;
}
}
И, конечно, использование в этом случае:
uint result = FloatUtil.NumbersBetween(1.5e-45f, 3.4e+38f);
В этом случае результатом является 2139081117
для этих чисел в C #, поскольку константное выражение 3.4e+38f
не компилируется в максимум диапазона с плавающей запятой. Однако использование float.MaxValue
(3.40282347E+38
) в качестве второго числа дает нам ожидаемое число, 2139095038
.