Предполагая, что есть число с плавающей запятой с 7 цифрами, как найти наименьшее число, которое можно добавить к этому числу с плавающей запятой?
Пример 1: 1234,567f + 0000,001f = 1234,568f
Пример 2: 0,01234567 + 0,00000001f = 0,01234568f
Предполагая, что есть число с плавающей запятой с 7 цифрами, как найти наименьшее число, которое можно добавить к этому числу с плавающей запятой?
Пример 1: 1234,567f + 0000,001f = 1234,568f
Пример 2: 0,01234567 + 0,00000001f = 0,01234568f
ОП добавил C#
после публикации этого C
ответа.
Оставлю это решение C в качестве эталона.
Распечатайте число в экспоненциальном формате и измените каждую цифру на «0» или «1».
float smallest_float_summable(float f, int digs) {
char buf[20];
sprintf(buf, "%.*e", digs - 1, f);
char *p = buf;
while (*p != 'e') {
if (isdigit(*p)) {
*p = '0' + (p[1] == 'e');
}
p++;
}
float y;
sscanf(buf, "%e", &y);
return y;
}
printf("%e\n", smallest_float_summable(1234.567f, 7));
// 1.000000e-03
Это не приведет к наименьшему, поскольку обычно число около 1/2 значения smallest_float_summable()
будет влиять на изменение, но, похоже, это соответствует намерению OP.
Чтобы получить наименьшее число, которое повлияет на некоторые изменения, просто используйте nextafter()
Функции
nextafter
определяют следующее представляемое значение в типе функции послеx
в направленииy
... C11dr §7.12.11.3 2
#include <math.h>
float smallest_change(float f) {
float dif = f - nextafterf(f, 0);
return dif;
}
[Редактировать]
@aka.nice правильно указывает, что даже меньше, может быть, около 1/2 dif
произведет изменение. Будет обдумывать это.
Чтобы найти наименьший эпсилон, вы можете начать с 10eN, где N равно 1, перейти к меньшему числу и добавить его. Затем сравните его с исходным числом.
number = x
N = 1
newnumber = 3
while (number <> newnumber){
newnumber = (number + 10eN)
N = N - 1
}
Then 10e(N+1) is the smallest epsilon.
number
было большим, как 1e30
, то N
нужно было бы начинать с большего значения, например 24 или больше, а не с 1.
- person chux - Reinstate Monica; 22.10.2015
nextafter
и вычесть. К сожалению, для этой полезной операции нет оболочки .NET. - person Ben Voigt   schedule 22.10.2015