Математически округлить с плавающей точкой до N знаков после запятой - PullRequest
0 голосов
/ 07 октября 2018

Я хочу округлить число с плавающей запятой / двойное число до n знаков после запятой.Но не в печати, а в целом.Например: пользовательский ввод: 2.3891 3, поэтому вывод должен быть 2.389или если пользовательский ввод 5.98441 4, вывод должен быть: 5.9844

#include <stdio.h>
#include <math.h>

int main () {

float num;
int decimals;

scanf("%f%d", &num, &decimals); //5.2381 2

int res = num; // res = 5

int power = 1;
int i = 0;
for(i = 0; i < decimals; i++)
    power*=10; // 1 * 10 * 10

int num3 = num * power; // num3 = 523
int num2 = num3 % power;//

float a = num2*1.0 / power*1.0;
// float a = 23*1.0/13.0;
printf("%f %d\n", a, power);

a = res + a;

printf("%f", a);

return 0;
}

В качестве вывода здесь я получаю: 2.390000.Я не хочу иметь эти нули и не хочу использовать фиксированный% .2f.Чего мне не хватает?

Ответы [ 3 ]

0 голосов
/ 07 октября 2018

В общем, это невозможно.Плавающая точка в C и C ++ в конечном итоге указывается в терминах базы, мантиссы, знака и показателя степени.

Десятичная дробная точка - это основание 10. На современном оборудовании это чрезвычайно редко встречается на практике.Некоторое раннее вычислительное оборудование (например, ENIAC, созданное в 1946 году) поддерживало десятичную с плавающей запятой.Однако такое представление довольно редко встречается в современном оборудовании.

Наиболее распространенные представления с плавающей запятой на современном оборудовании используют базу 2 (т.е. двоичную).Двоичная с плавающей запятой не может представлять все десятичные дроби.Попробуйте представить десятичное значение 0.1, используя сумму отрицательных степеней 2 (например, 1/2, 1/4, 1/8 и т. Д.).Вы обнаружите, что представление 0.1 включает бесконечный ряд в десятичном виде.Причина аналогична тому факту, что дробь 1/3 не может быть представлена ​​в конечном количестве десятичных знаков (то есть 0.33333...., где цифра 3 повторяется вечно).

Иррациональные значения (например, sqrt(2.0), pi и др.) Также не могут быть точно представлены в любой числовой базе с конечным числом цифр.Поэтому невозможно спроектировать тип с плавающей запятой фиксированного и конечного размера, который может точно хранить такие значения.

0 голосов
/ 07 октября 2018

Здесь вы делаете две вещи: 1) вычисление округленного значения числа и 2) печать этого числа.

вычисление округленного значения

Вы в значительной степениделаю это правильно.Имейте в виду, что при имплицитном преобразовании float в int C делает усечение, а не округление, поэтому:

float f = 1.9;
int i = f;

устанавливает i в 1, а не 2.В вашем случае, если вы вводите «1,229 2», вы рассчитываете значение 1,22, а не 1,23.Это может быть то, что вы хотите, но не можете.Если вы хотите округлить с вместо до нуля , вы можете изменить это:

int num3 = num * power;

на:

int num3 = 0.5 + num * power;

Печатьокругленное значение

Как только вы вычислили значение, вы печатаете его.Если вы хотите напечатать только количество десятичных разрядов, до которых вы округлили, вы можете использовать поле точности printf(), например:

printf("%.*f\n", decimals, a);
0 голосов
/ 07 октября 2018

В общем, эта задача невозможна, потому что преобразование IEEE 754 является представлением числа с плавающей запятой в двоичном виде или с плавающей запятой или с двойным.Таким образом, верхняя строка scanf("%f%d", &num, &decimals); //5.2381 2 преобразует десятичное число (основание 10) в двоичное число с плавающей запятой, и это преобразование в общем случае не является исключительным, поскольку у вас есть только ограниченное число битов.Вы можете уменьшить количество бит (двоичных), но это не определено в десятичной системе.При печати числа с плавающей (двойной) точностью возникает вторая неточность из-за преобразования двоичного в десятичное вычисление с плавающей запятой.

...