Использование float roundf(float x)
.
"Функции округления округляют свой аргумент до ближайшего целочисленного значения в формате с плавающей запятой, округляя полпути до нуля, независимо от текущего направления округления." C11dr §7.12.9.5
#include <math.h>
float y = roundf(x * 100.0f) / 100.0f;
В зависимости от вашей реализации float
числа, которые могут показаться наполовину, не являются. поскольку плавающая точка обычно ориентирована на базу-2. Кроме того, точное округление до ближайшего 0.01
во всех «промежуточных» случаях является наиболее сложным.
void r100(const char *s) {
float x, y;
sscanf(s, "%f", &x);
y = round(x*100.0)/100.0;
printf("%6s %.12e %.12e\n", s, x, y);
}
int main(void) {
r100("1.115");
r100("1.125");
r100("1.135");
return 0;
}
1.115 1.115000009537e+00 1.120000004768e+00
1.125 1.125000000000e+00 1.129999995232e+00
1.135 1.134999990463e+00 1.139999985695e+00
Хотя «1,115» находится «на полпути» между 1,11 и 1,12, при преобразовании в float
значение равно 1.115000009537...
и больше не «на полпути», а ближе к 1.12 и округляется до ближайшего float
из 1.120000004768...
«1,125» означает «на полпути» между 1,12 и 1,13, при преобразовании в float
значение в точности равно 1.125
и «на полпути». Он округляется до 1,13 из-за связи с четным правилом и округляется до ближайшего float
из 1.129999995232...
Хотя «1.135» находится «на полпути» между 1,13 и 1,14, при преобразовании в float
значение равно 1.134999990463...
и больше не «на полпути», а ближе к 1,13 и округляется до ближайшего float
из 1.129999995232...
Если используется код
y = roundf(x*100.0f)/100.0f;
Хотя «1.135» находится «на полпути» между 1,13 и 1,14, при преобразовании в float
значение равно 1.134999990463...
и больше не «на полпути», но ближе к 1,13, но неправильно округляет до float
из 1.139999985695...
из-за более ограниченной точности float
против double
. Это неправильное значение может рассматриваться как правильное в зависимости от целей кодирования.