Обращение «недопустимых операндов к бинарному выражению (« float »и« float »)» при использовании C - PullRequest
0 голосов
/ 27 апреля 2019

Выполняя задачу CS50 с набором 1 - Cash, я столкнулся со следующей проблемой при попытке написать свой код.Я объявил переменные в целое число.Почему это все еще происходит?Большое спасибо за помощь.

"недопустимые операнды для двоичного выражения (« float »и« float »)"

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

int main(){
    float owe_in_dollars;
    float owe_in_cent;
    int coin_count = 0;
    do
    {
    owe_in_dollars = get_float("Change: ");
    }while(owe_in_dollars<0);
    owe_in_cent = (int)(owe_in_dollars*100);
    if (owe_in_cent%(int)25 > 0){
       coin_count++;
    }
    printf("%i", coin_count);
}

1 Ответ

2 голосов
/ 27 апреля 2019

Есть несколько проблем с этим кодом, но я думаю, что конкретная проблема, которая вызывает ошибку компилятора,

if (owe_in_cent%(int)25 > 0){

owe_in_cent - это float. Нет никакой причины для того, чтобы это было число с плавающей запятой, так как вы присвоили его целочисленному значению. Но вы объявили это float, вот что это такое. 25 - это int, поэтому нет смысла приводить его к int, но с или без приведения оно будет преобразовано в float для выполнения арифметики с owe_in_cent, потому что все арифметические операторы требуют, чтобы эти операнды были одного типа. Ищите «обычные арифметические преобразования» для получения подробной информации, но суть в том, что эти автоматические преобразования всегда целочисленные & rarr; с плавающей точкой, никогда с плавающей точкой & rarr; целое число.

Тогда проблема обнаруживается, потому что оператор % требует, чтобы его операнды были целыми числами, а не с плавающей запятой. Есть математическая функция, которая может вычислять модуль с плавающей запятой, но вы действительно хотите целочисленную арифметику, поэтому лучше всего сделать owe_in_cent int, а не float.

И на самом деле, вы действительно должны привыкнуть использовать double для значений с плавающей запятой. float очень неточно, и, кроме видеочипов и встроенных процессоров, нет смысла использовать столь неточное представление. Это ничего не спасет.

Наконец, запомните два важных факта о плавающей запятой:

  1. Он не может точно представлять дроби, знаменатели которых не являются степенями двойки. Другими словами, 5.25 имеет точное представление, потому что .25 - это одна четверть, что является степенью двойки, но 5.26 не может быть точно представлено, и в итоге число будет немного больше или немного меньше 5.26. когда вы умножите это число на 100, вы получите что-то немного больше или чуть меньше 526.

  2. Преобразование числа с плавающей запятой в целое число просто отбрасывает дробную часть, независимо от того, насколько она близка к 1,0. Так, например, (int)525.9997 - это 525, а не 526. Вы должны увидеть проблему, которая может вызвать.

Существует библиотечная функция с именем round, которая округляет число с плавающей запятой до ближайшего целого числа, что, вероятно, является тем, что вы хотели.

...