8 / 8 / 6
Регистрация: 21.04.2018
Сообщений: 142

Работа с переменными типа float и double

22.06.2018, 20:04. Показов 4330. Ответов 39
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую всех форумчан. Я тут попытался реализовать программу, которая должна считать количество чисел после запятой (например, 13.456 ввели - вывело три числа), но... что-то происходит не так. Вроде алгоритму следовал, но почему-то программа не работает.. Отрабатывает и ничего не показывает, кроме чёрного квадрата Малевича.. Может кто скажет, в чём я допустил ошибку?

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
#include <iostream>
#include <iomanip>
using namespace std;
 
int main()
{
    double nmb;
    int floating_points_amount = 0;
    bool cont = false;
 
    nmb = nmb - (int)nmb; // оставляем это число без целой части для точности
 
    while (cont == false)
    {
                /// Алгоритм, который я хотел реализовать:
        // Делаем умножение числа на 10 до тех пор, пока число не станет целым, и во время исполнения
        // цикла заодно считаем кол-во чисел после запятых
 
        nmb *= 10;
 
        if (nmb / (int)nmb == 0)
            cont = true;
        else
        {
            floating_points_amount++;
            continue;
        }
    }
 
    // (nmb - (int)nmb) * 1000 (число без целой части превращаем в целое число,
    //                          умножая на кол-во чисел после запятой)
 
    cout << floating_points_amount;
 
    system("pause");
    return 0;
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
22.06.2018, 20:04
Ответы с готовыми решениями:

Работа с переменными типа float и double
Доброго времени суток всем, даммеры и госпопрограммеры :D Пытался я на днях реализовать программу, которая считает кол-во чисел после...

DrawEllipse с переменными double и float
Не могу понять почему функция рисования DrawEllipse не работает с типом double или float. Выдает ошибку &quot;The best overloaded...

Передача переменной типа double из c# в переменную типа float в SQL
Здравствуйте, имеется проблема с передачей данных из кода c# в бд SQL Имеется переменная типа double, к примеру double newPrice =...

39
Злостный нарушитель
 Аватар для Verevkin
10878 / 5817 / 1288
Регистрация: 12.03.2015
Сообщений: 26,855
25.06.2018, 09:58
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от N0VY Посмотреть сообщение
как сами числа после запятой тогда вывести?


Не благодари.
0
458 / 294 / 191
Регистрация: 23.06.2018
Сообщений: 678
25.06.2018, 14:20
N0VY, смотря про какой вариант вы говорите.
1. double: вообще здесь разные варианты. Можете создать строку и в неё записывать все цифры, какие находите, можете записывать их в long long, просто умножая на 10 и прибавляя единицу. Я предлагаю такой, если уж с double играть:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
{
    double nmb, copy, e;
    int floating_points_amount = 0;
    cout << "Enter number: ";
    cin >> nmb;
 
    nmb = abs(nmb);
    nmb = nmb - (int)nmb;
    copy = nmb;
    e = nmb / 1e14;
 
    // while  здесь
 
    cout << "Digits after point: " << floating_points_amount << endl;
    for (int i = 0; i < floating_points_amount; i++)
        copy *= 10;
    cout << "Fraction: " << copy << endl;
}
2. string:
C++
1
cout << "Fraction: " << str.c_str() + pos + 1 << endl;
3. char:
C++
1
2
3
4
5
6
7
8
9
// считывание всего до точки включительно
cout << "Fraction: ";
while (isdigit(ch))
{
    cout << ch;
    ch = cin.get();
    length++;
}
cout << endl << "Digits after point: " << length << endl;
0
8 / 8 / 6
Регистрация: 21.04.2018
Сообщений: 142
25.06.2018, 14:30  [ТС]
Лично я написал примерный синтаксис, только он выводит как-то всё неправильно. (ноут: сиауты в цикле для того, что-бы понимать, что происходит с числом в цикле) Зачем использовать копию в вашем первом примере, если можно использовать само число?

Добавлено через 666666 минут)
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
#include <iostream>
using namespace std;
 
void main()
{
    double nmb;
 
    cin >> nmb;
 
    // Кол-во чисел после запятых равно: 
 
    cout << (nmb - (int)nmb) << endl;
 
    // Само число равно
 
    while (nmb - (int)nmb != 0)
    {
        cout << nmb << endl;
        nmb *= 10;
    }
    cout << "Result number is " << nmb << endl;
 
    system("pause");
}
0
Злостный нарушитель
 Аватар для Verevkin
10878 / 5817 / 1288
Регистрация: 12.03.2015
Сообщений: 26,855
25.06.2018, 14:46
Цитата Сообщение от N0VY Посмотреть сообщение
только он выводит как-то всё неправильно
Чем тебе моя готовая, отлаженная функция не угодила-то, ёмаё?!
0
8 / 8 / 6
Регистрация: 21.04.2018
Сообщений: 142
25.06.2018, 14:55  [ТС]
Такое дело: для меня она слишком сложна в плане понимания. Я говорил уже, что таких вещей, как sscanf, strchr не знаю. С языка С не знаю, как пользоваться scanf'ом. Без обид

Добавлено через 666 минут
В общем, теперь такое дело: почему у меня эта программа не работает? Вроде-бы сделал то, что нужно, следовал сначала формуле для отделения целой части числа от самого числа, умножал полученное число на 10 до тех пор, пока nmb - (int)nmb не станет равным нулю.... Либо я использовал формулу не в том месте, либо мне нужно было её дополнить. Но как, если, например, нельзя делить числа с типом double или находить их %? Иногда я сам дивлюсь логике... которой нету.


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
#include <iostream>
using namespace std;
 
void main()
{
    double nmb;
 
    cin >> nmb;
 
    // Кол-во чисел после запятых равно: 
 
    cout << (nmb - (int)nmb) << endl;
 
    // Само число равно
 
    while (nmb - (int)nmb != 0)
    {
        cout << nmb << endl;
        nmb *= 10;
    }
    cout << "Result number is " << nmb << endl;
 
    system("pause");
}
0
Злостный нарушитель
 Аватар для Verevkin
10878 / 5817 / 1288
Регистрация: 12.03.2015
Сообщений: 26,855
25.06.2018, 14:57
Цитата Сообщение от N0VY Посмотреть сообщение
С языка С не знаю, как пользоваться scanf'ом. Без обид
Какие обиды, ты чо! Ты же знаешь, на кого обижаться не принято, правда?!
Цитата Сообщение от N0VY Посмотреть сообщение
для меня она слишком сложна в плане понимания
Почему я-то всё понимаю? Ведь я не программист, у меня даже компа нету. Как так-то, а?
Цитата Сообщение от N0VY Посмотреть сообщение
Я говорил уже, что таких вещей, как sscanf, strchr не знаю.
Ты это так хвастаешься своим невежеством? Это же стандартные функции С/С++ со времён царя Гороха. Эти функции с полнейшим описанием их работы (на всех языках) и примерами валяются в интернетах на каждом углу. Только руку протяни.
0
Злостный нарушитель
 Аватар для Verevkin
10878 / 5817 / 1288
Регистрация: 12.03.2015
Сообщений: 26,855
25.06.2018, 15:03
Считать цифры после точки в значении с плавающей точкой (!!!) - это дурь, потому что ты вводишь десятичное число как строку, а оно преобразовывается в двоичный double (знак + мантисса + экспонента) с погрешностью! Введёшь 0.7, а выведешь 0.69999999999999999999999999234745637646 5.

0
8 / 8 / 6
Регистрация: 21.04.2018
Сообщений: 142
25.06.2018, 15:19  [ТС]
Я это понимаю, но один товарищ (Bleach) сделал так, что-бы лишние числа не выводились и елести не было.

Добавлено через 1 минуту
Лично мои рассуждения таковы: нужно округлить полученное число, что-бы не было лишних цифр.

Добавлено через 2 минуты
Виноват, каюсь... Кстати, а как програмируем тогда без компа: с телефона чтоль?
0
Злостный нарушитель
 Аватар для Verevkin
10878 / 5817 / 1288
Регистрация: 12.03.2015
Сообщений: 26,855
25.06.2018, 15:34
Цитата Сообщение от N0VY Посмотреть сообщение
Лично мои рассуждения таковы: нужно округлить полученное число, что-бы не было лишних цифр.
Ага, сначала отбросить лишние разряды, а потом считать, что осталось?!
Логично, ага! Если ты округлил до целого, то число цифр посте точки всегда равно нулю. А если до N знаков после точки, то можешь опять получить бесконечное рациональное число.

-----------
С другой стороны, если ввод исходных данных один хрен как текста, то зачем текст переводить в double для подсчёта ЦИФР, блин, когда их можно посчитать НЕПОСРЕДСТВЕННО в введённом тексте?!



Цитата Сообщение от N0VY Посмотреть сообщение
Кстати, а как програмируем тогда без компа: с телефона чтоль?
Понятия не имею, как вы там программируете. Странный вопрос.
0
458 / 294 / 191
Регистрация: 23.06.2018
Сообщений: 678
25.06.2018, 16:43
Verevkin, человек хочет повеселиться с циферками. В конце концов заголовок темы "Работа с переменными типа float и double". И даже раздел "С++ для начинающих". Что мешает начинающим поэкспериментировать?
0
Злостный нарушитель
 Аватар для Verevkin
10878 / 5817 / 1288
Регистрация: 12.03.2015
Сообщений: 26,855
25.06.2018, 16:55
Цитата Сообщение от Bleach163 Посмотреть сообщение
человек хочет повеселиться с циферками. В конце концов заголовок темы "Работа с переменными типа float и double". И даже раздел "С++ для начинающих". Что мешает начинающим поэкспериментировать?
Да я просто спросил. Я всегда любую идею сразу пропускаю через фильтр здравого смысла, что по-русски звучит почти как "а оно мне надо?". Не понимаю людей, которые тратят время на ЗАВЕДОМО мёртворождённые задачи. Ведь, время - это самое дорогое из того, что у нас есть.

-------------
Я вижу, что пациент явно не шарит, и пытаюсь помочь именно сэкономить время на решение задачи, предложив более резонный и менее затратный метод. Но пациент активно сопротивляется и оправдывается своим невежеством, доказывая, что ему, как раз, надо именно "шашечки, а не ехать".

0
458 / 294 / 191
Регистрация: 23.06.2018
Сообщений: 678
25.06.2018, 17:26
Цитата Сообщение от N0VY Посмотреть сообщение
нельзя делить числа с типом double
Делить то их можно, только я не понимаю зачем вам здесь деление.
Цитата Сообщение от N0VY Посмотреть сообщение
почему у меня эта программа не работает
Максимальная точность double = 17 знаков => только числа от 10^17 точно не имеют дробной части.
Максимальное значение int = 2^31 - 1, дальше начинается переполнение.
То есть после того, как ваше число перевалит за 2.147.483.647, выражение nmb - (int)nmb практически никогда не будет равным нулю.
Если хотите оставить программу такой же - приводите к long long. Его максимум составляет чуть больше 9 * 10^19

Добавлено через 14 минут
Ошибся слегка, 17 знаков => от 10^16
max(long long) = 9 * 10^18
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
25.06.2018, 23:09
N0VY просто не может понять, что число с double хранится в виде a*2^N где a - мантисса, N - показатель степени.

В обычной же жизни мы имеем дело с числами вида a*10^N. Например 12.345 это 12345*10^(-3). А комп (по крайней мере большинство из современных) считают в бинарном виде, поэтому умножать им проще на степень 2ки. Поэтому для компа характерны числа наподобие 0b100101*0b10^0b11001 . Если перевести из бинарного формата чисел в десятичные, то это то же самое что 37*2^25 . Но умножение на 2 нельзя превратить в умножение на 10 (по крайней мере пока умножаем на целое число 2ек). Ну примерно так же как 1024 байта в килобайте нельзя превратить в 1000 - остаток из 24 останется и будет портить точность. Именно поэтому у вас ничего и не работает.

Поэтому вас два пути -
1) использовать строку а не число. Комп без вашей помощи ничего посчитать с этой строкой не сможет, но вот изучить её цифры (символы) сможет вполне (типа "две цифры после запятой, и там ещё прибавок с 10 в степени")

2) использовать double в том виде, в котором она на самом деле. Т.е. что например используется число 5434*2^-10 (или 5434/1024)
0
8 / 8 / 6
Регистрация: 21.04.2018
Сообщений: 142
26.06.2018, 11:47  [ТС]
(Обращение к Верёвкину) Невежество? Верёвкин, если я не знаю вещей, которые вы наверняка знаете (в случае языка С) это значит, что я невежественен и я сопротивляюсь? Я просто не понимаю вашей проги.. И у меня "молоко на губах не обсохло". Дело всё в практике, которую мои учителя по программирования, выскажусь мягко, "в сторонку посылали" : используют метод "делай, как хочешь, главное - сделай (даже списывать разрешают, но я не люблю этим пользоваться)". А это единственное место, где я могу учиться програмированию. Ну и этот форум - единственное, что меня спасает во время обучения. Спасибо большое этому форуму за то, что он есть, кстати говоря! Думать я умею, но слишком сложно, и всё из-за того, что у меня нет практики. Поэтому я прошу помощи у тех, кто знает лучше, может высказать свою мысль о том, как делать ту или иную вещь. Самому всё выискивать? Если бы всё было так легко... со временем. которое я трачу на делание д/з.
(Ближе к делу): алгоритм, который я хочу реализовать (но реализовал неудачно) проще, чем "дважды два", это я сам чёрт подери понимаю, но НЕТ: он не работает, хотя должен, просто обязан, я понимаю, что он должен работать так!! Кстати: поэксперементировать хотел я, действительно, но я хочу использовать данную программу для реализации программы сокращения числа... Наверняка пустяки для таких профессионалов, как вы, но хардово для такого новичка, как я. Если бы меня понимали...

Добавлено через 3 минуты
Кстати, что такое мантисса?
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
26.06.2018, 12:34
Алгоритм, конечно, придумать можно, но

Если надо анализировать количество чисел после запятой, стоит анализировать символьные данные, а не double представление.
0
8 / 8 / 6
Регистрация: 21.04.2018
Сообщений: 142
26.06.2018, 12:35  [ТС]
Почему символьные?
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
26.06.2018, 13:17
потому-что double не даёт точного представления десятичных дробных. Теряется информация о количестве знаков.

Добавлено через 3 минуты
О чем, собственно, говорит камрад Verevkin.
Считать цифры после точки в значении с плавающей точкой (!!!) - это дурь, потому что ты вводишь десятичное число как строку, а оно преобразовывается в двоичный double (знак + мантисса + экспонента) с погрешностью! Введёшь 0.7, а выведешь 0.69999999999999999999999999234745637646 5.
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
26.06.2018, 17:18
Цитата Сообщение от N0VY Посмотреть сообщение
Думать я умею, но слишком сложно, и всё из-за того, что у меня нет практики
расскажи,как умножение на 2 превратить в умножение на 10. По твоему мнению.

P.S. https://ru.wikipedia.org/wiki/... й_точности
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
26.06.2018, 17:28
Цитата Сообщение от Verevkin Посмотреть сообщение
C++
1
2
double dummy;
if (!sscanf(s, "%f", &dummy)) return -1;
%lf
0
Злостный нарушитель
 Аватар для Verevkin
10878 / 5817 / 1288
Регистрация: 12.03.2015
Сообщений: 26,855
26.06.2018, 19:04
Цитата Сообщение от Croessmah Посмотреть сообщение
%lf
зависит от компайлера. тестовую прогу собирал на mingw, она работает.
Да и значение далее не используется, это только вариант проверки, что строка введена правильно.
Цитата Сообщение от N0VY Посмотреть сообщение
Почему символьные?
О май гад, ты читаешь, что я тебе пишу? В двоичную форму без погрешности переводятся только целые числа. Дробные, в общем случае, представляют из себя рациональные числа (периодические дроби). Поэтому считать цифры после точки в double - это анриал. Но, поскольку на вход ты подаёшь именно строку символов типа "±123.4567", то имеет смысл посчитать десятичные цифры от точки до конца. Это и есть цель твоей задачи.



Мама, роди меня обратно...

З.Ы. Короче, найди статью Антона Григорьева "Неочевидные особенности вещественных чисел", и читай до полного просветления.
Ссылку дать не могу. Сам найдёшь.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.06.2018, 19:04

непонятка с переменными типа float
Здравствуйте! может кто подскажет, а то не почму к примеру создаю переменную типа ftoot 12.23 самое интересное когда смотрю...

Switch возможно ли работать с переменными типа float?
и если возможно, то почему на такой код switch (min) { case (r.USA): { } } , где min:float ...

Преобразование типа double во float
Добрый день! Возникла такая проблема. Написал в 1 строчке то, как мне нужно сделать и, конечно же, мне выдает ошибку о том, что не удается...

Неправильно отнимаются числа типа float(double)
Сразу говорю, что перезайти в решение - не вариант. Итак, у меня есть малюсенькая нейронная сеть, но это так, что б понимать код, но...

Проверка на корректность ввода типа double и float
Как сделать, чтобы выводила ошибку при некорректном вводе?


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

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

Новые блоги и статьи
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru