Я изо всех сил пытался найти сумасшедшую ошибку в некотором коде C ++ и сузил ее до этого небольшого раздела. Я поместил в простой файл main.c для его отладки и не могу понять, почему математика с плавающей запятой округляется, а не должна.
// setup the variables for this simple case
int writep = 672;
float offset = 672.000122;
int bufferSize = 2400;
float bufferSizeF = (float)bufferSize;
float outPointer = (float)writep - offset; // outPointer: -0.000122070313
if(outPointer < 0.0f){
printf("outPointer: %.9f \n", outPointer); // outPointer: -0.000122070313
outPointer += bufferSizeF; // outPointer SHOULD be: 2399.9998779296875
printf("outpointer: %.9f \n", outPointer); // outPointer: 2400.000000000
}
Кто-то … пожалуйста, объясните. Благодарю.
2400.000000000
а также 2399.9998779296875
слишком близки для стандарта float
дифференцировать их. Попробуй это:
#include<iostream>
int main() {
std::cout << (float)2399.9998779296875 << "\n";
}
Это, вероятно, даст 2400
в качестве вывода.
IEEE 754 одинарной точности float
может содержать только от 7 до 8 значащих десятичных цифр. Если вам нужно большее количество значащих цифр, используйте двойную точность double
,
В стандарте IEEE 754 числа с плавающей точкой неравномерно распределены по оси чисел. Плотность значений с плавающей запятой выше около 0, чем около 2400, поэтому округление выполняется, когда значение около 2400.
Вот картинка, чтобы проиллюстрировать это:
https://www.google.fi/search?q=IEEE+754+distribution&BIW = 1920&БиГ = 895&Источник = lnms&TBM = Isch&са = Х&вед = 0ahUKEwj-tKOWkMzPAhUEDywKHRdRAEUQ_AUIBigB # imgrc = rshe5_x1ZXFoKM% 3A