Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
-3 / 0 / 1
Регистрация: 29.03.2018
Сообщений: 396

Откуда ошибка в укорачивании дробной части?

20.03.2024, 14:43. Показов 1464. Ответов 29
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Появляется странная ошибка во второй функции: число drob считается неверно и мало похоже на дробную часть входного числа x.


Вот пример работы при makeShorter(123456.012345, 3)
teI: 123456
drob: 0.015625
teS1: 0.015
stof: 0.015
vihod=123456


То есть drob получает неправильное значение, а потом ещё и к vihod не прибавляется дробная часть.
Из-за чего так происходит?


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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//Из string в float
float stringToFloat(string x)
{
    int c1 = 0; //Целая часть
    float c2 = 0; //Дробная часть
    int dot = 0; //Индекс точки
 
 
    //Поиск индекса точки
    for (int i = 0; i < x.length(); i++)
    {
        if (x[i] == '.' || x[i] == ',')
        {
            dot = i;
            break;
        }
    }
 
 
    //Получение целой части
    int mul = 1;
    for (int i = dot - 1; i >=0; i--, mul*=10)
    {
        c1 += mul * (int(x[i]) - 48);
    }
 
 
    //Получение дробной части
    mul = 10;
    for(int i = dot + 1; i < x.length(); i++, mul *= 10)
    {
        c2 += (float(int(x[i])) - 48) / mul;
    }
 
 
 
    float teF = c1 + c2; //Возвращаемое число
 
 
    return teF;
}
 
 
//Укорачивание дробной части
float makeShorter(float x, int kolvo)
{
    int teI = x; //Целая часть
    float drob = x - float(teI); //Дробная часть
 
    cout << "teI: " << teI << endl;
    cout << "drob: " << drob << endl;
 
 
    //Перевод дробной части в стоку
    stringstream ts1;
    ts1 << drob;
    string teS = ts1.str();
 
 
    //Если укорачивать не нужно
    if (teS.length() <= (kolvo + 2))
        return x;
 
 
    //Укорачивание
    string teS1 = "";
    for (int i = 0; i < (kolvo + 2); i++)
    {
        teS1 += teS[i];
    }
 
    cout << "teS1: " << teS1 << endl;
    cout << "stof: " << stringToFloat(teS1) << endl;
 
    
    //Итог
    float vihod = float(teI) + stringToFloat(teS1);
 
 
    return vihod;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.03.2024, 14:43
Ответы с готовыми решениями:

Ошибка при вычислении дробной части
в чем ошибка ? не вычисляет дробную часть Dim str1() As String = Split(TextBox2.Text, &quot;,&quot;) Dim r4 As Double If...

Найти среднее арифметическое между суммами 1-й и 2-й цифр целой части и 2-й и 3-й цифрами дробной части числа
Номер 3. Дробная часть числа состоит из 3-х цифр. Найти среднее арифметическое между суммами 1-й и 2-й цифрами 2-й и 3-й цифрами дробной...

Дано положительное вещественное число Х. Определить, равна ли первая цифра его дробной части последней цифре целой части
Дано положительное вещественное число Х. Определить, равна ли первая цифра его дробной части последней цифре целой части. Данные должны...

29
459 / 246 / 15
Регистрация: 29.10.2014
Сообщений: 1,084
21.03.2024, 11:27
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от ChioraYaz Посмотреть сообщение
Нужно просто сделать так,
Ну посмотрите еще:
C++
1
cout << round(14.245*100)/100;
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6296 / 3018 / 1053
Регистрация: 01.06.2021
Сообщений: 11,464
21.03.2024, 11:54
Цитата Сообщение от commun Посмотреть сообщение
14.245*100
1424.5 идеально представляется в двоичном виде (32-bit float):
01000100101100100001000000000000
Но если будет, например, 14.244, то формула работать не будет, ибо в двоичном виде (32-bit) 1424.4 выглядит как:
01000100101100100000110011001101
тогда как, на самом деле, это бесконечная дробь с повторяющейся частью 1100
Даже если возьмешь 64-bit float или триллион битов, все равно погрешность)

ChioraYaz, выше я и TheCalligrapher вам писали, что "обрезка дробной части" лишена смысла для чисел с плавающей запятой. Еще раз говорю, настрой просто вывод, не трогай число.
0
459 / 246 / 15
Регистрация: 29.10.2014
Сообщений: 1,084
21.03.2024, 13:14
Цитата Сообщение от Royal_X Посмотреть сообщение
1424.5 идеально представляется
Что, опыт с 14.244 не удался?
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6296 / 3018 / 1053
Регистрация: 01.06.2021
Сообщений: 11,464
21.03.2024, 13:41
commun, что мешает самому попробовать?

C++
1
2
3
4
5
6
7
8
#include <iostream>
#include <cmath>
using namespace std;
int main() 
{
    cout.precision(50);
    cout << round(14.244*100)/100;
}
Добавлено через 12 минут
commun, вообще, все ещё проще. Эти округления на самом деле здесь ни при чем, просто некоторые числа, как писал выше, не представляются без погрешности:

C++
1
2
3
4
5
6
7
8
include <iostream>
using namespace std;
int main() 
{
    cout.precision(50);
    cout << 14.24 << '\n';
    cout << 14.24f;
}
0
459 / 246 / 15
Регистрация: 29.10.2014
Сообщений: 1,084
21.03.2024, 13:42
Цитата Сообщение от Royal_X Посмотреть сообщение
что мешает самому попробовать?
C++
1
2
cout << round(14.244 * 100) / 100 << endl;
//14.24
Только без #include <cmath> и cout.precision(50);
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6296 / 3018 / 1053
Регистрация: 01.06.2021
Сообщений: 11,464
21.03.2024, 13:50
commun, <cmath> здесь вообще никакой роли не играет, это заголовок, который нужно подключить при работе с round. Касательно, cout.precision(50), то его писал только для презентации погрешности. Даже если без него ты получаешь на выводе 14.24, это не означает, что нет погрешности. Просто дефотный precision для cout меньше 50, поэтому ты не видишь погрешность.
0
459 / 246 / 15
Регистрация: 29.10.2014
Сообщений: 1,084
21.03.2024, 13:54
В Basic есть функция округления: Round(ОкругляемоеЗначение, ТребуемоеКоличествоЗнаковПослеЗапятой) (значение 5 округляется в большую сторону). В C++ round(Number) - это отбрасывание дробной части. Нужно два знака - умножили на 100, отбросили дробную часть, разделили на 100.

Добавлено через 4 минуты
Цитата Сообщение от Royal_X Посмотреть сообщение
это заголовок, который нужно подключить при работе с round
Согласен, но у меня и без этого заголовка файл .cpp не барахлит.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
21.03.2024, 15:26
Цитата Сообщение от commun Посмотреть сообщение
Нужно два знака - умножили на 100, отбросили дробную часть, разделили на 100.
Это так не работает. Некоторым не доходит.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,306
21.03.2024, 17:47
Цитата Сообщение от commun Посмотреть сообщение
C++
1
2
cout << round(14.244 * 100) / 100 << endl;
//14.24
Только без #include <cmath>
Это как это??? Что такое round без #include <cmath>?

Цитата Сообщение от commun Посмотреть сообщение
и cout.precision(50);
Но "без cout.precision" - это то же самое, что cout.precision(6). То есть не бывает никакого "без cout.precision". cout.precision есть всегда.
0
459 / 246 / 15
Регистрация: 29.10.2014
Сообщений: 1,084
21.03.2024, 19:35
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Это как это???
Откуда я знаю? Возвращает 0.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.03.2024, 19:35

Определить равна ли сумма k цифр дробной части заданного вещественного числа сумме цифр целой части
Помогите доделать задание, исправьте пожалуйста код!!! Срочно! Задание: Выполнить задания, выделяя цифры числа, хранящегося в переменной...

Определить равна ли сумма цифр из целой части действительного числа суммы такого же количества цифр из дробной части
Пожалуйста помогите написать блок-схему(алгоритм)умоляю.Пожалуйста

Определения, равна сумма цифр целой части вещественного числа сумме такого же количества цифр в дробной части
Нада написать 2 программки 1. Определения, равна сумма цифр целой части вещественного числа сумме такого же количества цифр в дробной...

Определить равна ли сумма цифр из целой части действительного числа суммы такого же количества цифр из дробной части
Определить равна ли сумма цифр из целой части действительного числа суммы такого же количества цифр из дробной части.

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


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

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Новые блоги и статьи
Сезонность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru