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

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

20.03.2024, 14:43. Показов 1358. Ответов 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
6221 / 2917 / 1046
Регистрация: 01.06.2021
Сообщений: 10,794
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
6221 / 2917 / 1046
Регистрация: 01.06.2021
Сообщений: 10,794
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
6221 / 2917 / 1046
Регистрация: 01.06.2021
Сообщений: 10,794
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
12938 / 6805 / 1821
Регистрация: 18.10.2014
Сообщений: 17,227
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
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru