2010-03-31 2 views
10

Давайте рассмотрим мы имеем double R = 99.999999; (которые могут быть получены в результате какого-либо другого вычисления), теперь требуемый выход 99,99Усечение двойной без округления в C

Я попытался с помощью printf("%.2lf",R); но это Округление Значение. Как получить желаемый результат? (предпочтительно с использованием printf)

ответ

0

Можете ли вы умножить на 100, а затем усечь на целое число? Затем вы можете отформатировать результат, как и доллары и цента. Простое разделение на 100 может вернуть вас обратно в квадрат из-за проблем с плавающей точкой.

+0

Не совсем. Стандартные двойные представления с плавающей запятой точны до 15 цифр. Поэтому, если ОП не будет иметь дело с цифрами в десяти миллиардах долларов, он должен быть в порядке. В любом случае умножение запускается в одинаковые проблемы с представлением с плавающей запятой. –

2

sprintfsprintf он в буфер, а затем помещает символ NUL в два байта мимо '.'

Then printf Ваша последняя строка с использованием промежуточной.

0

Как насчет использования double trunc(double) от GLibC?

+4

Потому что не все используют GLibC. –

+1

@Billy Вопрос не говорит «Я не хочу использовать GLibC», так что ответ действительно, правильно? :) – Romain

+1

Да, это действительно. Вот почему я не спустил вниз. Это не обязательно делает это хорошо. :) –

10
#include <math.h> 
... 
    printf("%.2f", floor(100 * R)/100); 
+1

+1, но так как вопрос отмечен C++, возможно, также предоставляет способ C++ iostream? –

+1

Есть ли какие-то нечетные случаи, когда это дает неправильный ответ? Я не уверен, но существует ли значение с плавающей запятой f и целое число n такое, что f меньше точного значения n/100, но результат с плавающей запятой f * 100 больше или равен n? Конечно, вы можете сомневаться в том, что f усечен «неправильно», поскольку в «базовом 10 пространстве» он представляет диапазон, который охватывает маркер 0.01. –

+1

Возможны ли отрицательные числа? С -99.999, умножьте на -9999.9, пол -10000, а результат -100. –

4

Все, что вам нужно сделать, это вычесть .005 из числа и магически printf будет вести себя по вашему желанию: всегда округлять вниз.

+2

Если число отрицательное. Тогда он взорвется. –

+0

Вы избили меня до редактирования ... он не взорвался. Это просто делает наоборот. В этом случае добавьте .005. – frankc

+0

Не кажется ли это чем-то более сложным, чем благородный ответ на отсутствие выгоды?Конечно, вы сохраняете деление и умножение, но вы торгуете им за зависимость от отрасли (что еще хуже) и код, который гораздо менее четко выражает ваши намерения. –

0

Другое решение, с помощью слепков:

... 
printf("%.2lf", (double) ((int) (R * 100))/100); 
+0

Это неверно, если R может быть отрицательным. –

+0

Я тестировал в Borland C++ Builder и работал как с отрицательными, так и с положительными значениями. – Juliano

0

Другой способ, действительно подписать агностиком: Е ("% d% d \ п.", (Целое) г, абс ((INT) (г * 100)% 100));

2

Если у вас есть, использовать fmod() рубить хвост double:

double rounded = R - fmod(R, 0.01); 
// Now just print rounded with what you were using before 

Это имеет преимущество работы такой же, если R является положительным или отрицательным.

Смежные вопросы