Я думаю, что какой бы язык вы ни использовали, вы бы указали, как хранятся числа с плавающей запятой. Я знаю, что Java делает это, используя определенный стандарт IEEE (754, я думаю).
Если он не указан, я думаю, вы могли бы просто выполнить свою собственную проверку, добавив 0,5 к 1, чтобы увидеть, изменится ли фактическое число. Если это так, то добавьте 0,25 к 1, 0,125 к 1 и т. Д., Пока число не изменится, например:
float a = 1;
float b = 0.5;
int bits = 0;
while (a + b != a) {
bits = bits + 1;
b = b / 2;
}
Если бы у вас было только 3 бита мантиссы, то 1 + 1/16 было бы равно 1.
Тогда вы исчерпали свои биты мантиссы.
Вам может понадобиться, чтобы базовое число было 2, а не 1, поскольку IEEE754 использует подразумеваемое «1+» в начале.
EDIT:
Похоже, что описанный выше метод может иметь некоторые проблемы, так как он дает 63 бита для системы, которая явно имеет 4-байтовые числа с плавающей запятой.
Является ли это результатом промежуточных результатов (я сомневаюсь в этом, поскольку тот же код с явными приведениями [while (((float)(a + b) != (float)(a))
] имеет аналогичные проблемы) или (более вероятно, я полагаю) вероятность того, что значение единицы a
можно представить с битами ближе к дробному b
путем корректировки показателя степени, я пока не знаю.
На данный момент лучше полагаться на информацию о языке, которую я упомянул выше, например, на использование IEEE754 (если такая информация имеется).
Я оставлю проблемный код в качестве ловушки для осторожных игроков. Может быть, кто-то с большим знанием с плавающей запятой, чем я, могу оставить записку, объясняющую, почему он действует странно (не догадка, пожалуйста: -).
РЕДАКТИРОВАТЬ 2:
Этот фрагмент кода исправляет это, гарантируя, что промежуточные продукты хранятся в числах с плавающей точкой. Оказывается, Джонатан Леффлер был прав - это были промежуточные результаты.
#include <stdio.h>
#include <float.h>
int main(void) {
float a = 1;
float b = 0.5;
float c = a + b;
int bits = 1;
while (c != a) {
bits = bits + 1;
b = b / 2;
c = a + b;
}
printf("%d\n",FLT_MANT_DIG);
printf("%d\n",bits);
return 0;
}
Этот код выводит (24,24), чтобы показать, что вычисленное значение соответствует значению в заголовочном файле.
Хотя написано на C, оно должно быть применимо к любому языку (особенно к тому, где информация недоступна в заголовке или в силу того, что это указано в документации по языку). Я тестировал только на C, потому что Eclipse так долго запускается на моем Ubuntu box: -).