Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
8 / 8 / 6
Регистрация: 21.04.2018
Сообщений: 142

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

22.06.2018, 20:04. Показов 4280. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Расчёт периметра прямоугольника по координатам вершин
Maks 18.07.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Вычислить периметр прямоугольника, заданного координатами своих вершин на плоскости. Решение: Создан документ со следующими. . .
Подсчёт частоты трёхбуквенных слов в тексте
Maks 18.07.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Выясните, сколько раз в предложенном тексте встречается каждое трехбуквенное слово. Решение: Создан документ с единственным. . .
Сумма и количество положительных элементов в чётных строках массива
Maks 18.07.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Вычислить сумму и количество положительных элементов массива, расположенных в четных строках. Решение: Создан документ с. . .
Поиск произведения положительных чётных чисел в последовательности
Maks 18.07.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Дана произвольная последовательность целых чисел. Найти произведение положительных четных чисел данной последовательности. . . .
Обработка трёх чисел: утроение и возведение в степень
Maks 18.07.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Даны три действительных числа. Утроить те из них, значения которых неотрицательны, и возвести в четвертую степень отрицательные. . . .
Расчёт стоимости яблок по весу
Maks 18.07.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Написать программу вычисления стоимости некоторого количества (по весу) яблок. Решение: Создан документ, с табличной частью. . .
сукцессия 30. Фосфорный и азотный замки по "честному" закону лимитирования Либиха
anaschu 16.07.2026
Основные достижения за последние дни 1. Механизм отложенного высвобождения фосфора Добавлен специальный пул для медленного разложения меланизированных гиф ЕСМ Реализована разная скорость. . .
Запрет пометки на удаление и отмены проведения
Maks 16.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "ПутевойЛист" разработанного в КА2. Задача: запретить помечать на удаление и отменять проведения путевого листа при условии, если он сдан. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru