В настоящее время я работаю над программой банковских терминалов для лабораторных занятий в своем университете.C strtod() возвращает неправильные значения
То, что меня отталкивает, - это функция, которая должна принимать входные данные пользователя для передачи, проверять, соответствует ли он всем требованиям, и если да, возвращает значение, предоставленное программе.
Наш наставник сумасшедший о всех средствах обеспечения ввода, и поэтому я должен вызвать ошибку при любом несоответствии. Слишком высокая стоимость? Ошибка. Отрицательное или нулевое значение? Ошибка. Число точнее 0,01? Ошибка. Символы, отличные от цифр и точек, на входе? Ошибка.
Из-за этого моя функция, безусловно, сложна, но я в порядке с этим. То, что подталкивает меня к стене, состоит в том, что функции atof()
и strtod()
читают цифры как-то неправильно.
long double take_amount()
{
char input[21];
bool success, correct;
unsigned long int control1;
long double amount, control, control2, control3;
do
{
success = true, correct = true;
printf("\t\tAmount:\t\t");
success = scanf("%20[^ \t\n]c", input);
__fpurge(stdin);
correct = check(input, 'b');
amount = strtod(input, NULL);
printf("\n\tGOT %.20Lf\n", amount); ///
control = amount * 100;
control1 = (unsigned long int)floor(control);
control2 = (long double) control1;
control3 = control2 - control;
printf("\n\tGOT2 %.20Lf\n", control3); ///
if (control3 != 0)
{
if (control3 >= 1 || control3 <= -1)
{
printf("\n\t\tWe are sorry, but for the safety reasons it is impossible to transfer");
printf("\n\t\tsuch a great amounts while online. If you really wish to finalize");
printf("\n\t\tthis operation, please, visit the closest division of our bank.");
printf("\n\t\tWe are sory for the inconvenience and wish you a pleasent day.");
press_enter();
}
correct = false;
printf("\nDAMN\n"); ///
}
if (amount <= 0)
{
correct = false;
printf("\nGOD DAMN\n"); ///
}
if(success == false || correct == false)
{
printf("\n\t\tInvalid input, please try again.\n\n");
}
else
{
printf("\t\t\t\t%.2Lf\n", amount);
printf("\n\t\tIs it correct input? ((Y)es/(N)o/(E)xit)");
if (accept())
{
break;
}
else
{
continue;
}
break;
}
}while (1);
return amount;
Насколько мои функции, используемые здесь идет, check()
проверяет, является ли строка содержит только допустимые символы (цифры и точка), press_enter()
ждет для ввода-пресс, чтобы оставить в главное меню и accept()
читает только у/п/e, вернуть true
по y, false
на n и выходит в меню на e.
Длительная часть с контрольными переменными - это мое решение для проверки того, является ли число не точнее 0,01. К сожалению, это не работает из-за strtod()
.
Моя проблема в том, что strtod()
на самом деле не работает! Даже с действительно номерами медикаментов, находящимися далеко от нижнего или переполнения, возвращаемое значение не соответствует введенному. Некоторые примеры:
Enter the amount you would like to deposit. Amount: 1234.45 GOT 1234.45000000000004547474 Enter the amount you would like to deposit. Amount: 0.999 GOT 0.99899999999999999911
Не исключено, что это моя вина, но через несколько часов с этим кодом, я все еще не мог придумать с рабочим решением, и поэтому я прошу вас помочь, зажимные internauts переполнения стека.
Есть ли способ исправить показания strtod()
? Если нет, есть ли другой способ взять этот ввод, который позволит мне проверить все, что нужно проверить?
EDIT: ВНИМАНИЕ, ПОЖАЛУЙСТА!
Если я еще не заявил, что мой наставник не самый простой парень, с которым я работаю, я делаю это сейчас.
Он ПРЕДЛАГАЕТ использовать формат DOUBLE для хранения БАЛАНСА, хранящегося на счетах. Я знаю это, потому что один из моих коллег получил свою программу REJECTED для использования двухтактной, долларовой конструкции.
Я очень благодарен вам за помощь здесь, так как вы можете как-то решить эту проблему? Я должен использовать двойной тип для хранения денег. Я также должен проверить, не было ли буквы на входе (scanf()
, установленный на %Lf
, будет просто вырезать все цифры без конца), ИСПЫТАТЬ, если ввод не точнее, чем 0,01, ИМЕЕТ принять структуру xxx.xx ввода. Какие-либо предложения?
'strtod' и связанные с ним функции, а' double' сам по себе не может быть «исправлен». В основном потому, что с ними нет ничего плохого: [Что каждый программист должен знать о арифметике с плавающей точкой] (http://floating-point-gui.de/). Найдите решение, которое не использует тип с плавающей точкой. – usr2564301
Добро пожаловать в мир чисел с плавающей точкой; из-за того, как они представлены внутри, существуют десятичные значения, которые невозможно точно представить. –
Это характер арифметики с фиксированной точностью. Так же, как нет десятичного числа фиксированной длины, которое дает 1 при умножении на 3, нет двоичного числа фиксированной длины, которое дает 1 при умножении на 10. –