сколько разных чисел от 1,5 х 10 ^ (- 45) до 3,4 х 10 ^ 38? - PullRequest
0 голосов
/ 19 июля 2009

Сколько различных чисел от 1,5 х 10 -45 до 3,4 х 10 38 (IEE754 с одинарной точностью)?

Ответы [ 5 ]

23 голосов
/ 19 июля 2009

Предполагая, что вы говорите о диапазоне в плавающем элементе одинарной точности IEEE (1,5 x 10 ^ -45 - это наименьшее положительное значение, которое оно может представлять, и 3,4 x 10 ^ 38 наибольшее положительное значение)

у нас были бы следующие возможные раскладки для 4 байтов, которые занимало бы это число:

0 00000000 00000000000000000000000 = 0
0 00000000 00000000000000000000001 = 1.5 x 10^-45
......
0 11111110 11111111111111111111111 = 3.4 x 10^38
0 11111111 00000000000000000000000 = Infinity
0 11111111 xxxxxxxxxxxxxxxxxxxxxxx = NaNs

Что должно дать нам 2139095037 цифр между ними.

6 голосов
/ 20 июля 2009

Конечно, это можно сделать программно, для любых двух чисел с плавающей запятой вообще. «Лексикографический индекс» - это упорядоченный индекс числа с плавающей запятой, доступный, среди прочего, потому что 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.

4 голосов
/ 19 июля 2009

Я пытаюсь угадать, о чем на самом деле твой вопрос. 1.4E-45 - это наименьшее число (иногда называемое epsilon ), которое может быть представлено в сингле IEEE 754. Наибольшее число составляет примерно 3,4E38. Сингл находится на компьютере и хранится в 32-битном значении, а один бит используется для знака. Это оставляет 31 бит для представления чисел от epsilon до максимального значения. Если мы предположим, что все возможные 31-битные числа приводят к действительному синглу, то ответ на ваш вопрос будет 2 ^ 31 или 2 147 483 648. Как было указано, это предположение неверно, так как некоторые значения не являются числом или NaN .

Подробнее о числах с плавающей запятой можно прочитать в Википедии

0 голосов
/ 19 июля 2009

Я думаю, что вы имеете в виду целые числа. А также вы имеете в виду между 3,4 * 10 ^ 38 и 1,5 * 10 ^ 45, потому что 1,5 * 10 ^ 45 больше, чем другой. В любом случае ответ такой же, как и с меньшими числами. Я предполагаю, что вы хотите исключить эти два числа так:

Сколько существует чисел от 2 до 10? Ответ 10-2-1 = 7. Действительно, 3,4,5,6,7,8,9 - это 7 номеров. Итак, «формула»:

Сколько чисел находится между a и b? Ответ б-а-1

Так 1,5 * 10 ^ 45-3,4 * 10 ^ 38 -1 = 15 * 10 ^ 44-34 * 10 ^ 37 -1 = (15 * 10 ^ 7) * 10 ^ 37-34 * 10 ^ 37 -1 = (15 * 10 ^ 7-34) * 10 ^ 37 -1 = (150000000-34) * 10 ^ 37 -1 = 149999966 * 10 ^ 37 -1 или 1499999659999999999999999999999999999999999999

0 голосов
/ 19 июля 2009

Это не совсем программирование.

bc говорит (для целых чисел):

1.5*10^45
1500000000000000000000000000000000000000000000.0
3.4*10^38
340000000000000000000000000000000000000.0
1500000000000000000000000000000000000000000000.0-340000000000000000000000000000000000000.0
1499999660000000000000000000000000000000000000.0
...