Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Mr_Cipa
1 / 1 / 2
Регистрация: 13.06.2015
Сообщений: 25
#1

Почему 5/9=0, если тип float? - C++

12.05.2016, 13:44. Просмотров 1748. Ответов 34
Метки нет (Все метки)

Объектно-ориентированное программирование в С++ Лафоре Р.
3 глава, упрожнение 2
Кликните здесь для просмотра всего текста
Напишите программу, предлагающую пользователю осуществить перевод
температуры из шкалы Цельсия в шкалу Фаренгейта или наоборот, а затем
осуществите преобразование. Используйте в программе переменные веще-
ственного типа. Взаимодействие программы с пользователем может вы-
глядеть следующим образом:
Нажмите 1 для перевода шкалы Цельсия в шкалу Фаренгейта,
2 для перевода шкалы Фаренгейта в шкалу Цельсия: 2
Введите температуру по Фаренгейту: 70
Значение по Цельсию: 21.111111


Рабочий вариант, а с строкой rezault = 5 / 9 * (temp - 32) ; результат всегда ноль. Я так понял, что 5 / 9 дает 0, только вот не могу понять почему не 0.55555555555555555555555555555556 тип переменной же используется с плавающей точкой. Объясните плз. И подскажите может это дело все можно было написать как то красивей и элегантней

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
 
using namespace std;
 
int main()
{
    setlocale(LC_ALL, "Russian");
 
    int options;
    float rezault, temp;
    
    cout << "\t\t\t=== Конвертер температуры ===\n" << "1. Фаренгейт >>> Цильсия\n" << "2. Цельсия >>> Фаренгейт\n";
    cin >> options;
 
    while (options != 1 && options != 2)
    {
        system("cls");
        cout << "\t\t\t=== Конвертер температуры ===\n" << "1. Фаренгейт >>> Цильсия\n" << "2. Цельсия >>> Фаренгейт\n\a\t\t    === Ошибка ввода.Повторите Ввод.===\n";
        cin >> options;
    }
 
    switch (options)
    {
    case 1:
        system("cls");
        cout << "\t\t\t === Фаренгейт >>> Цильсия ===\nВведите температуру по Фаренгейту: ";
        cin >> temp;
        rezault = (temp - 32) * 5 / 9 ;
        cout << rezault << "\n";
        break;
    case 2:
        system("cls");
        cout << "\t\t\t === Цельсия >>> Фаренгейт ===\nВведите температуру по Цельсию: ";
        cin >> temp;
        rezault = temp * 9 / 5 + 32;
        cout << rezault << endl;
        break;
        
    }
    
    return 0;
}
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.05.2016, 13:44
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Почему 5/9=0, если тип float? (C++):

Почему при объявлении переменных тип float выдает ошибку
Подскажите, пожалуйста, почему когда я объявляю переменные как float, то...

cannot convert `float' to `float*. Почему так происходит?
всем привет, помогите исправить ошибки... а то голова мало варит уже, а завтра...

Почему диапазон значений у типа float больше, чем у типа int, если они оба занимают 4 байта?
Почему диапазон значений флоат больше чем у инта, если они оба занимают 4...

Тип данных float
1) Какое масимальное целое может содержать float? 2) Точность дробной части у...

Тип данных float
Подскажите в каких случаях используют тип данных float. Гугл ничего не дал,...

Тип float в массиве
Доброго времени суток! Объявил float a ; Но при выводе консоль выводит...

34
nimazzzy
Заблокирован
12.05.2016, 13:52 #2
Цитата Сообщение от Mr_Cipa Посмотреть сообщение
Я так понял, что 5 / 9 дает 0, только вот не могу понять почему не 0.55555555555555555555555555555556
Потому что ты делишь целые числа. Деление int дает в итоге int. Это значит, вся дробная часть - в труху. Дели, например, 5/9.0
1
dcshowcousa
26 / 18 / 97
Регистрация: 22.10.2015
Сообщений: 303
12.05.2016, 13:58 #3
Mr_Cipa, или используй явное приведение типов
C++
1
(float)5/9
1
rikimaru2013
C++ Game Dev
2471 / 1140 / 348
Регистрация: 30.11.2013
Сообщений: 3,709
12.05.2016, 15:04 #4
Лучший ответ Сообщение было отмечено Mr_Cipa как решение

Решение

Mr_Cipa, потому, что компилятор может производить операции только над одинаковыми типами - отсюда
запись
C++
1
float k = 5/9;
будет условно преобразована в запись
C++
1
float k ( static_cast<float>( int(5).operator/( int(9) ) ) );
уже в момент деления у вас останиться запись
C++
1
float k ( static_cast<float>( int(0) ) );
2
Evg
Эксперт CАвтор FAQ
18940 / 6901 / 513
Регистрация: 30.03.2009
Сообщений: 19,443
Записей в блоге: 30
12.05.2016, 16:32 #5
http://www.cyberforum.ru/c-beginners/thread1267080.html#post6711356
1
nimazzzy
Заблокирован
12.05.2016, 16:38 #6
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
потому, что компилятор может производить операции только над одинаковыми типами
Это как так? Это почему?
1
Stitch Igorek
47 / 47 / 31
Регистрация: 02.04.2016
Сообщений: 308
Завершенные тесты: 1
12.05.2016, 17:02 #7
Цитата Сообщение от nimazzzy Посмотреть сообщение
Это как так? Это почему?
это потому что нельзя прибавить цифру 2 к помидору - компилятор преобразовывает помидор к цифре, и только потом прибавляет.
2
rikimaru2013
12.05.2016, 17:04
  #8

Не по теме:

Stitch Igorek, результатом будет "жираф" - очевидно же ж!

0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7007 / 3300 / 450
Регистрация: 04.12.2011
Сообщений: 9,137
Записей в блоге: 5
12.05.2016, 17:14 #9
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Stitch Igorek, результатом будет "жираф" - очевидно же ж!
Если есть такая перегрузка операции сложения:
C++
1
2
3
4
Giraffe operator+(Tomatto& tomatto, int ne_tomatto)
{
//------------------------складываем
}
то будет Жираф.
3
Manowar
1552 / 484 / 164
Регистрация: 12.03.2016
Сообщений: 1,825
Завершенные тесты: 1
12.05.2016, 22:26 #10
работаю в visual studio 2010 скопировал твою программу полностью от себя добавил #include <conio.h> для задержки в конце getch() работает и считает все четко без ошибок иерархия типов данных float выше чем int должно все работать случайно не вводишь temp = 32
0
nmcf
6247 / 5559 / 2529
Регистрация: 14.04.2014
Сообщений: 23,375
12.05.2016, 23:02 #11
Какая иерархия? Если первым выполнится 5 / 9, то дальше умножение обнулит любой тип.
0
IGPIGP
12.05.2016, 23:12
  #12

Не по теме:

Цитата Сообщение от nmcf Посмотреть сообщение
Какая иерархия?
Иерархия как иерархия, а операции равного приоритета выполняются слева направо. В тех странах где левая рука и правая рука на своих местах. :)

0
nmcf
12.05.2016, 23:13
  #13

Не по теме:

Он про иерархию типов говорит, а не операций.

0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7007 / 3300 / 450
Регистрация: 04.12.2011
Сообщений: 9,137
Записей в блоге: 5
12.05.2016, 23:18 #14

Не по теме:

Цитата Сообщение от nmcf Посмотреть сообщение
Он про иерархию типов говорит, а не операций.
это мелочь по сравнению с тем, что я не знаю как ему плюсануть. мановар, заметил правильно, - оно считает то что нужно.:D

мановар, в первом посту ниже спойлера сам вопрос. Там 5/9*(temp-32)=0
Ну то есть по Фаренгейту всё.
0
nimazzzy
13.05.2016, 07:34
  #15

Не по теме:

Цитата Сообщение от Stitch Igorek Посмотреть сообщение
это потому что нельзя прибавить цифру 2 к помидору - компилятор преобразовывает помидор к цифре, и только потом прибавляет.
В программе я легко могу написать сложение int c float (что под капотом - не важно в контексте темы). Перегрузка оператора сложения - хоть с какими типами делай действия и получай любой тип. Как это относится к тому что автор получает 0?

0
Manowar
1552 / 484 / 164
Регистрация: 12.03.2016
Сообщений: 1,825
Завершенные тесты: 1
13.05.2016, 09:11 #16
Если взять отдельное выражение rez=5/9 и объявить float rez, то будем получать 0 так как 5 и 9 int. Но если в выражение ввести 5.0 или 9.0, как было замечено ранее, то получаем уже 0.55555, так как появилась переменная типа float. Не поленился скачал Лафоре стр.65 похожий пример, все так же считает, никаких ошибок. Про использование перенменных разных типов, тот же самый Лафоре стр.75, С и С++ предполагают, что смешивание типов данных произошло сознательно и является задумкой программиста, и поэтому не мешают ему реализовывать свои идеи.......
Подобная либеральность увеличивает вероятность допущения ошибок.
Хотелось бы услышать что то от Mr_Cipa. В какой среде и каким компилятором пользуется и решил ли эту проблему (у меня ее просто нет)
0
Stitch Igorek
47 / 47 / 31
Регистрация: 02.04.2016
Сообщений: 308
Завершенные тесты: 1
13.05.2016, 09:51 #17
Цитата Сообщение от nimazzzy Посмотреть сообщение
В программе я легко могу написать сложение int c float (что под капотом - не важно в контексте темы). Перегрузка оператора сложения - хоть с какими типами делай действия и получай любой тип. Как это относится к тому что автор получает 0?
автор получает "0" потому, что делит целое число 5 на целое число 9, - в результате будет целое число(в нашем случае 0), а уже потом автор этот "0" преобразовывает к типу float. об этом писалось на протяжении всей темы.
А про помидор я написал не для того чтобы перегрузку реализовывали, а для того чтобы понимали, что если написать например 5 / 9.0, то компилятор прежде чем делить, пятерку приведет к типу double(заметьте - не float, а именно double, так как неявное приведение типов всегда идет в сторону большей точности). потом выполняется деление, потом записывается результат деления в переменную типа float(уже явное приведение типов, так сами написали, что переменная имеет тип float)

Добавлено через 33 секунды
Цитата Сообщение от nimazzzy Посмотреть сообщение
В программе я легко могу написать сложение int c float (что под капотом - не важно в контексте темы). Перегрузка оператора сложения - хоть с какими типами делай действия и получай любой тип. Как это относится к тому что автор получает 0?
автор получает "0" потому, что делит целое число 5 на целое число 9, - в результате будет целое число(в нашем случае 0), а уже потом автор этот "0" преобразовывает к типу float. об этом писалось на протяжении всей темы.
А про помидор я написал не для того чтобы перегрузку реализовывали, а для того чтобы понимали, что если написать например 5 / 9.0, то компилятор прежде чем делить, пятерку приведет к типу double(заметьте - не float, а именно double, так как неявное приведение типов всегда идет в сторону большей точности). потом выполняется деление, потом записывается результат деления в переменную типа float(уже явное приведение типов, так сами написали, что переменная имеет тип float)
0
nimazzzy
Заблокирован
13.05.2016, 10:06 #18
Цитата Сообщение от Stitch Igorek Посмотреть сообщение
автор получает "0" потому, что делит целое число 5 на целое число 9, - в результате будет целое число(в нашем случае 0), а уже потом автор этот "0" преобразовывает к типу float.
Я это же и написал в первом своем сообщении.
Цитата Сообщение от Stitch Igorek Посмотреть сообщение
А про помидор я написал не для того чтобы перегрузку реализовывали, а для того чтобы понимали, что если написать например 5 / 9.0, то компилятор прежде чем делить, пятерку приведет к типу double(заметьте - не float, а именно double, так как неявное приведение типов всегда идет в сторону большей точности)
Это можно не расписывать, я в курсе. Но компилятор может и производит работу с разными типами. Компилятор компилирует именно запись 5/9.0, а не 5.0/9.0. Деление вещественных чисел делает уже процессор (по инструкциям сгенерированным компилятором), а не компилятор. С какими типами работает компилятор никак не объясняет получение 0 в итоге. Что же мешает ему из int(5).operator/( int(9) ) сделать вещественное число? Жалко что ли? А говорить, что компилятор работает с операторами только с одинаковыми типами - это не корректно.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7007 / 3300 / 450
Регистрация: 04.12.2011
Сообщений: 9,137
Записей в блоге: 5
13.05.2016, 10:06 #19
Цитата Сообщение от Stitch Igorek Посмотреть сообщение
если написать например 5 / 9.0, то компилятор прежде чем делить, пятерку приведет к типу double(заметьте - не float, а именно double, так как неявное приведение типов всегда идет в сторону большей точности)
Потому что 9.0 это double. Укажите явно float (преобразованием или суффиксом) и будет к float преобразовываться. А rikimaru2013, идею для новичка правильно обрисовал. Про
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
компилятор может производить операции только над одинаковыми типами
погорячился. С кем не бывает. В конце концов с точки зрения контракта операцию:
C++
1
T operator+(A, B)
можно считать преобразующей. И если не лезть под капот, то порядок приведения мог быть и такой: A->T, B->T и потом T=T+T.
0
Manowar
1552 / 484 / 164
Регистрация: 12.03.2016
Сообщений: 1,825
Завершенные тесты: 1
13.05.2016, 10:14 #20
У меня то все работает без проблем это то как объяснить
0
13.05.2016, 10:14
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.05.2016, 10:14
Привет! Вот еще темы с решениями:

Тип памяти переменной float
Доброго время суток всем! помоги найти ответ на вопрос, что за тип памяти...

Тип float нельзя сдвигать?
Пытаюсь сделать так: float data; ... f.open(&quot;primerus_bit.txt&quot;,...

Преобразование типа char в тип float
При считывании из файла чисел (каждое число расположено на новой строке, целая...

Тип - матрица, состоящяя из float'ов 4x4
Как правильно объявить такой тип??


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru