Как ограничить количество знаков после запятой в c windows forms

Обновлено: 04.07.2024

Округление значения

В этой статье мы будем работать с типом данных decimal, но акцентируем внимание не на его размере и точности, а на дополнительной функциональности, присущей этому типу в отличие от двух других вариантов. В частности, мы будем использовать четыре статических метода округления, которые доступны только для десятичных значений. Конечно, это можно использовать и для одно- и двойной чисел точности тоже. Однако в этих случаях необходимо сначала привести к или преобразовать значение в decimal или использовать члены класса Math.

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

Floor и Ceiling

Статические методы Floor и Ceiling выполняют аналогичные функции усечения: они удаляют дробную часть числа и возвращают целое число. Опять же целое число возвращается в десятичной структуре. Основное различие между этими методами и Truncate является то, что направление округления фиксируется как для положительных и отрицательных чисел. Для функции Floor округление всегда вниз, а Ceilin всегда вверх, как можно видеть в результатах примере кода ниже.

Контролируемые округления

Три описанных выше способа могут быть использованы во многих сценариях. Тем не менее, они ограничены работой с целыми значениями и они не работают по нормальным правилам математического округления. Там, где требуется дополнительные функциональные возможности, может быть использован метод Round. Этот метод дает больший контроль над округлением, позволяет гибко работать с числами.

В заключительной части этой статьи мы рассмотрим метод Round более подробно.

Простое округление

Самый простой способ, которым можно использовать метод Round, это с одним параметром, содержащим число, которое надо изменить. При использовании таким образом возвращаемое значение содержит целое число, которое ближе всего к переданному значению.

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

Можно было бы ожидать, что оба значения округляются в сторону увеличения и метод возвратит 2 и 3 соответственно. Однако, по умолчанию, этот метод использует правило средней точки (медианы), которое гласит, что когда значение округляется ровно на полпути между двумя целыми числами, всегда выбирается ближайшее значение.

Правила медианы

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

Чтобы задать правило, параметр MidpointRounding добавляется к вызову метода.

Округление до указанного количества десятичных знаков

Все примеры до сих пор рассматривали округление значения, когда в результате возвращается целое число. Однако метод Round позволяет также округление до определенного количества знаков после запятой. Это достигается путем определения необходимого количества знаков после запятой в качестве второго параметра метода, как показано в следующих примерах:

Здесь правило медианы по умолчанию "ToEven" применяется для округления, за исключением того, что конченая цифра округляется до ближайшего четного числа.

Вы можете изменить правило медианы, используется при округлении до количества знаков после запятой. Чтобы сделать это, просто добавьте значение MidpointRounding в качестве третьего параметра:

Из-за потери точности, которая может быть результатом представления десятичных значений как чисел с плавающей точкой и выполнения арифметических операций с плавающей запятой, в некоторых случаях в Round(Double, Int32) может отсутствовать округление среднего значения до ближайшего четного значения цифр десятичной позиции. Это показано в следующем примере, где 2.135 округляется до 2,13 вместо 2.14. Это происходит потому, что внутренний метод умножает значение на 10 разрядов, и операция умножения в этом случае страдает от потери точности.

Таким образом, в статье мы попробовали немного прояснить ситуацию с округлением decimal. Как видим, все не так уж и сложно, но есть нюансы, которые необходимо иметь в виду при написании программ. Кстати, программы на заказ пишу и я. Недорого, быстро и с гарантией.

Мой код для двух знаков после запятой.\

Изменение на "^\d*\.\d$")) e.Handled = правда;

выход

This is the output

Возможный Дубликат : Ограничьте двойник двумя знаками после запятой Я хочу отобразить числа в определенном формате в Objective C. Здесь я просто хочу показать числа с точностью до двух. Предположим, у меня есть такие числа, как 25.5; Тогда я хочу показать номер, как указано ниже. 25.5 => 25.50

Для класса я должен написать программу, которая преобразует градус Фаренгейта в градус Цельсия и наоборот. Результат должен быть округлен до первого знака после запятой. Я попробовал функцию round несколькими способами, но безуспешно. temp=float(input(Enter a temperature value to convert: )).

Вы можете сделать это без regex, просто проверив, где находится десятичный разделитель в вашем тексте, а затем убедившись, что это на 2 меньше длины строки (1 десятичный знак и 1 меньше для длины массива)

Я просто пытался

и это сработало как надо. Он ограничивал ввод одной цифрой после десятичной точки. Но вы можете ввести более одной десятичной точки, а затем и больше цифр. Так что вы можете либо попробовать

или что-то вроде

Мне нужно округлить до 1 знака после запятой Если мой номер 80.02, мне нужно, чтобы он был 80.1. пытался Math.ceil( (80.02).toFixed(1) ) but this rounds the number up to 81 Как я могу этого достичь?

Как вы округлить float или Double вплоть до энного знака после запятой в свинью. Например f(3.999999, 1) = 3.9 f(3.42317, 2) = 3.42 f(1.03, 1) = 1.0 Мне действительно нужно только округлить до 1-го знака после запятой, но я решил оставить этот вопрос общим. Я видел вопрос pig round decimal to two.

Создайте новый TextBox, который наследует TextBox как

теперь используйте это текстовое поле и используйте DecimalValue для установки или получения вашего значения

Похожие вопросы:

Я использую выражение ниже, может ли кто-нибудь посоветовать, как я могу округлить его до 1 знака после запятой, пожалуйста? =Round(Count(Fields!FieldName.Value)) / 8562 *100 & % Это и есть.

См. следующий код: NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemFreeSize]; float totalSpaceInMB = (([fileSystemSizeInBytes longLongValue] /1024.0)/1024.0); Здесь.

Возможный Дубликат : Как вы округляете до 1 десятичного знака в Javascript? Мое значение-1.450, и я должен округлить его до 1 знака после запятой. Я хочу 1.450 = 1.5 в Javascript может ли любое тело.

Возможный Дубликат : Ограничьте двойник двумя знаками после запятой Я хочу отобразить числа в определенном формате в Objective C. Здесь я просто хочу показать числа с точностью до двух. Предположим.

Для класса я должен написать программу, которая преобразует градус Фаренгейта в градус Цельсия и наоборот. Результат должен быть округлен до первого знака после запятой. Я попробовал функцию round.

Мне нужно округлить до 1 знака после запятой Если мой номер 80.02, мне нужно, чтобы он был 80.1. пытался Math.ceil( (80.02).toFixed(1) ) but this rounds the number up to 81 Как я могу этого достичь?

Как вы округлить float или Double вплоть до энного знака после запятой в свинью. Например f(3.999999, 1) = 3.9 f(3.42317, 2) = 3.42 f(1.03, 1) = 1.0 Мне действительно нужно только округлить до 1-го.

Я хочу округлить данное число до одного десятичного знака, но если это целое число, то выход должен иметь один ноль после десятичного знака. Пример: Ввод: 24.66, 24.0002 , 24.62 Выход : 24.7, 24.0 .

На данный момент у меня есть этот SQL: SELECT Count(create_weekday), create_weekday, Count(create_weekday) * 100 / (SELECT Count(*) FROM call_view WHERE ( create_month = Month(Now() - INTERVAL 1.

У меня есть двойная переменная 0.0449999 , и я хотел бы округлить ее до 1 знака после запятой 0.1 . Я использую Kotlin, но решение Java также полезно. val number:Double = 0.0449999 Я попытался.

Вы также можете посмотреть на округление/округление до банкиров со следующей перегрузкой:

Там больше информации об этом здесь.

Ответ 2

Ответ 3

Лично я никогда никого не кручу. Держите его как можно более решительным, так как округление - это немного красная селедка в CS. Но вы хотите отформатировать данные для своих пользователей, и с этой целью я считаю, что string.Format("", number) - хороший подход.

Ответ 4

Если вам нужна строка

Но помни! Округление не является дистрибутивным, т.е. round(x*y) != round(x) * round(y) . Поэтому не делайте округления до самого конца вычисления, иначе вы потеряете точность.

Ответ 5

//конвертировать до двух знаков после запятой

Ответ 6

Обратите внимание, что Decimal.Round() использует другой метод, чем Math.Round();

Ответ 7

Я знаю его старый вопрос, но обратите внимание на следующие различия между Math round и Формат строки:

Ответ 8

Ответ 9

Одна вещь, которую вы можете проверить, - это механизм округления Math.Round:

Кроме этого, я рекомендую подход Math.Round(inputNumer, numberOfPlaces) по сравнению с * 100/100, потому что он чище.

Ответ 10

Вы можете указать количество цифр, которые вы хотите округлить, используя Math.Round(YourNumber, 2)

Вы можете прочитать здесь.

Ответ 11

string a = "10.65678";

decimal d = Math.Round(Convert.ToDouble(a.ToString()), 2)

Ответ 12

Ответ 13

Math.Floor(123456.646 * 100)/100 Вернуться 123456.64

Ответ 14

Давайте посмотрим, что произойдет, если вы хотите округлить до 3-го знака после запятой:

Как видите, первый раунд() является правильным, если вы хотите округлить среднюю точку. Но второй раунд() это неправильно, если вы хотите округлить.

Это относится к отрицательным числам:

Итак, IMHO, вы должны создать свою собственную функцию обтекания для Math.Round(), которая соответствует вашим требованиям. Я создал функцию, в которой параметр roundUp = true означает округление до следующего большего числа. То есть: 0,7125 раундов до 0,713 и -0. 0,7125 раундов до -0.712 (потому что -0.712> -0.713). Это функция, которую я создал и работает для любого количества десятичных знаков:

Переменная 'corrector' предназначена для исправления неточностей работы с плавающими или двойными числами.

Как можно округлить значение с плавающей запятой (например, 37,777779) до двух десятичных знаков (37,78) в C?

Вы не можете правильно округлить само число, потому что float (и double ) не являются десятичными числами с плавающей точкой - они являются двоичными числами с плавающей точкой - поэтому округление до десятичных позиций не имеет смысла. Вы можете округлить вывод, однако. Это не бессмысленно; это неточно. Есть большая разница. Какое округление вы ожидаете? Половина или округление до ближайшего четного?

Если вы просто хотите округлить число для целей вывода, тогда "%.2f" строка формата действительно является правильным ответом. Однако, если вы действительно хотите округлить значение с плавающей запятой для дальнейших вычислений, работает что-то вроде следующего:

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

Как отметили некоторые другие, из-за особенностей представления с плавающей запятой, эти округленные значения могут быть не совсем «очевидными» десятичными значениями, но они будут очень и очень близки.

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

Можно ли изменить его для поддержки округления до произвольной точности? @slater Когда вы говорите «произвольная точность», вы спрашиваете о округлении, например, до трех вместо двух десятичных знаков, или используете библиотеки, которые реализуют десятичные значения с неограниченной точностью? Если первое, внесите, как я надеюсь, очевидные корректировки постоянной 100; в противном случае выполните точно такие же вычисления, как показано выше, только с любой библиотекой с множественной точностью. @DaleHagglung Бывший, спасибо. Является ли корректировка для замены 100 на pow (10, (int) требуемая точность)? Ага. Для округления после k десятичных знаков используйте масштабный коэффициент 10 ^ k. Это должно быть действительно легко увидеть, если вы запишите некоторые десятичные значения вручную и поиграете с коэффициентами, кратными 10. Предположим, вы работаете со значением 1.23456789 и хотите округлить его до 3 десятичных знаков. Доступная вам операция округляется до целого числа . Итак, как вы перемещаете первые три знака после запятой, чтобы они остались от десятичной точки? Надеюсь, понятно, что вы умножаете на 10 ^ 3. Теперь вы можете округлить это значение до целого числа. Затем вы кладете обратно три младших разряда, разделив их на 10 ^ 3. Могу ли я сделать эту работу doubles слишком как-то? Кажется, не выполняет ту работу, которую я хочу :( (использую floor и ceil ).

Использование % .2f в printf. Он печатает только 2 десятичных знака.

@albert Это также имеет то преимущество, что нет потери float дальности, поскольку val * 100 может переполниться.

Предполагая, что вы говорите о значении для печати, ответ Эндрю Колесона и Арака верен:

Но учтите, что если вы хотите округлить число до 37,78 для внутреннего использования (например, для сравнения с другим значением), то это не очень хорошая идея из-за способа работы чисел с плавающей запятой: обычно вы этого не делаете хотите сделать сравнение равенства для плавающей запятой, вместо этого используйте целевое значение +/- сигма-значение. Или закодируйте число в виде строки с известной точностью и сравните это.

Смотрите ссылку в ответе Грега Хьюгилла на связанный вопрос , который также объясняет, почему вы не должны использовать плавающую точку для финансовых расчетов.

Голосовали за решение вопроса о том, что может быть за вопросом (или вопрос, который должен был быть за вопросом!). Это довольно важный момент. На самом деле 37.78 можно представить именно с плавающей запятой. Float имеет от 11 до 12 цифр для точности. Этого должно быть достаточно, чтобы адрес 3778 377,8 или все виды 4 десятичных цифр. @HaryantoCiu да, честно, я немного отредактировал свой ответ. динамическая точность: printf("%.*f", (int)precision, (double)number);

Как насчет этого:

-1: а) это не сработает для отрицательных чисел (хорошо, пример положительный, но все же). б) вы не упоминаете, что невозможно сохранить точное десятичное значение в float правила округления в контексте комментария @Daniil округляются до ближайшего

Если вы хотите написать в C-строку:

@ Синан: Почему редактировать? @AraK: Нет, ты должен позаботиться о размере :). Используйте snprintf (). @aib: Я думаю, потому что / ** / - это комментарии в стиле C, а вопрос помечен для C C89 допускает только / ** / - стиль, C99 вводит поддержку // - стиля. Используйте неработающий / старый компилятор (или включите режим C89), и вы не сможете использовать // - стиль. Сказав, что это 2009, давайте рассмотрим их как стиль C и C ++.

Нет способа округлить a float до другого, float потому что округленное float может быть не представимым (ограничение чисел с плавающей запятой). Например, допустим, вы округлили 37,777779 до 37,78, но ближайшее представимое число - 37,781.

Тем не менее, вы можете "округлить" float , используя функцию форматирования строки.

Это ничем не отличается от высказывания «нет способа разделить два числа с плавающей точкой и получить число с плавающей точкой, потому что разделенный результат может быть не представимым», что может быть в точности верно, но не имеет значения. Поплавки всегда неточны, даже для чего-то такого базового, как сложение; всегда предполагается, что на самом деле вы получаете «число с плавающей точкой, которое наиболее близко соответствует точному округленному ответу». Я имел в виду, что вы не можете округлить float до n десятичных знаков, а затем ожидать, что результат всегда будет иметь n десятичных знаков. Вы все еще получите float , но не тот, который вы ожидали.

Кроме того, если вы используете C ++, вы можете просто создать такую ​​функцию:

Затем вы можете вывести любой двойник myDouble с n местами после десятичной точки с помощью такого кода:

Вы все еще можете использовать:

Это усекает в десятичной точке (то есть будет производить 37), и он должен округлить до двух мест после десятичной точки. Однако округление до двух знаков после запятой является тривиальным вариантом (но все же следует упомянуть в ответе; ZeroCool, хотите добавить правку?): Float roundedValue = ceilf (valueToRound * 100.0) / 100.0; Почему это решение не так популярно? Это работает именно так, как должно с минимальным кодом. Есть ли какое-то предостережение с этим?

В C ++ (или в C с приведением в стиле C) вы можете создать функцию:

Тогда std::cout << showDecimals(37.777779,2); будет производить: 37,78.

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

Всегда используйте printf семейство функций для этого. Даже если вы хотите получить значение как число с плавающей запятой, лучше всего использовать snprintf для получения округленного значения в виде строки, а затем анализировать его с помощью atof :

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

  • Для некоторых значений он будет округляться в неправильном направлении, потому что умножение на 100 изменяет десятичную цифру, определяющую направление округления, с 4 на 5 или наоборот, из-за неточности чисел с плавающей запятой
  • Для некоторых значений умножение, а затем деление на 100 не происходит в обратном порядке, а это означает, что даже если не происходит округления, конечный результат будет неправильным

Чтобы проиллюстрировать первый тип ошибки - иногда неправильное направление округления - попробуйте запустить эту программу:

Вы увидите этот вывод:

Обратите внимание, что значение, с которого мы начали, было меньше 0,015, и поэтому математически правильный ответ при округлении до 2 десятичных знаков равен 0,01. Конечно, 0,01 не совсем точно представляется в виде двойного числа, но мы ожидаем, что наш результат будет двойным, ближайшим к 0,01. Использование snprintf дает нам этот результат, но использование round(100 * x) / 100 дает нам 0,02, что неправильно. Зачем? Потому что 100 * x дает нам точно 1,5 в результате. Умножение на 100, таким образом, меняет правильное направление на округление.

Для иллюстрации второго рода ошибки - результат иногда быть неправильно из - за * 100 и на / 100 самом деле не быть обратным друг друга - мы можем сделать подобное упражнение с очень большим числом:

Наш номер теперь даже не имеет дробной части; это целочисленное значение, просто хранится с типом double . Таким образом, результат после округления должен быть таким же, как мы начали, верно?

Если вы запустите программу выше, вы увидите:

К сожалению. Наш snprintf метод снова возвращает правильный результат, но подход «умножить-затем-округлить-затем-разделить» не дает результатов. Это потому , что математически правильное значение 8631192423766613.0 * 100 , 863119242376661300.0 является не совсем представимо в виде двойной; самое близкое значение 863119242376661248.0 . Когда вы делите это обратно на 100, вы получаете 8631192423766612.0 - число, отличное от того, с которого вы начали.

Надеюсь, это достаточная демонстрация того, что использование roundf округления до числа десятичных разрядов не работает, и что вы должны использовать snprintf вместо этого. Если вам кажется, что это ужасный хак, возможно, вы будете уверены, что это именно то, что делает CPython .

+1 за конкретный пример того, что не так с моим ответом и схожими с ним, благодаря странности IEEE с плавающей запятой и предоставлению простой альтернативы. Я был на периферии, довольно давно, много усилий вложил в печать, и друзья мне безопасны для обходных значений с плавающей запятой. Я полагаю, что проделанная работа может появиться здесь. Гм . Извините за слово салат в конце там, который сейчас слишком поздно редактировать. То, что я хотел сказать, было ". много усилий было приложено к принфу и друзьям, чтобы сделать их безопасными . "

Использование float roundf(float x) .

«Функции округления округляют свой аргумент до ближайшего целочисленного значения в формате с плавающей запятой, округляя полпути до нуля, независимо от текущего направления округления». C11dr §7.12.9.5

В зависимости от вашей float реализации, числа, которые могут показаться на полпути, не являются. поскольку с плавающей точкой, как правило, ориентируется на базу-2. Кроме того, точное округление до ближайшего 0.01 во всех «промежуточных» случаях является наиболее сложной задачей.

Хотя «1.115» является «полпути» между 1.11 и 1.12, при преобразовании в float значении не является 1.115000009537. и больше не « на полпути», но ближе к 1.12 и патронам к ближайшему float из 1.120000004768.

«1.125» означает «на полпути» между 1.12 и 1.13, при преобразовании float в значение точно 1.125 и «на полпути». Она округляет в стороне 1,13 из - за связи с даже правил и округляется до ближайшего float из 1.129999995232.

Хотя «1.135» есть « на полпути» между 1.13 и 1.14, когда преобразуется в float значение не является 1.134999990463. и больше не « на полпути», но ближе к 1,13 и патронов к ближайшему float из 1.129999995232.

Если код используется

Хотя «1.135» является «на полпути» между 1.13 и 1.14, при преобразовании float в значение равно 1.134999990463. и больше не «на полпути», а ближе к 1.13, но неправильно округляет до float из- 1.139999985695. за более ограниченной точности float сравнения double , Это неправильное значение может рассматриваться как правильное в зависимости от целей кодирования.

Я сделал этот макрос для округления чисел с плавающей точкой. Добавьте это в свой заголовок / существо файла

Это усекает, но вопрос требует округления. Кроме того, он подвержен ошибкам округления в операциях с плавающей запятой.

Вот n количество десятичных знаков

-1 по четырем причинам: 1) отсутствие объяснения, 2) уязвимость переполнения буфера - это увлекает, и поэтому вполне возможно , аварии, если dval это огромный 3) сверхъестественный if / else блок , где вы делаете одно и то же в каждой отрасли и 4) слишком сложное использование sprintf для создания спецификатора формата для второго sprintf вызова; проще использовать .* и передавать двойное значение и количество десятичных знаков в качестве аргументов для одного и sprintf того же вызова.

Определение кода:

Полученные результаты :

Позвольте мне сначала попытаться обосновать причину добавления еще одного ответа на этот вопрос. В идеальном мире округление не имеет большого значения. Однако в реальных системах вам, возможно, придется столкнуться с несколькими проблемами, которые могут привести к округлению, которое может не соответствовать вашим ожиданиям. Например, вы можете выполнять финансовые расчеты, где окончательные результаты округляются и отображаются для пользователей в виде 2 десятичных знаков; эти же значения хранятся с фиксированной точностью в базе данных, которая может включать в себя более 2 десятичных знаков (по разным причинам; оптимального количества мест для хранения не существует . зависит от конкретных ситуаций, которые должна поддерживать каждая система, например, крошечные предметы, цены на которые - доли копейки за единицу); и вычисления с плавающей запятой, выполняемые для значений, где результаты плюс / минус эпсилон. Я сталкиваюсь с этими проблемами и разрабатываю свою собственную стратегию на протяжении многих лет. Я не буду утверждать, что сталкивался с каждым сценарием или имею лучший ответ, но ниже приведен пример моего подхода, который преодолевает эти проблемы:

Предположим, что 6 знаков после запятой считаются достаточной точностью для вычислений с плавающей запятой / двойными числами (произвольное решение для конкретного приложения) с использованием следующей функции / метода округления:

Округление до 2 знаков после запятой для представления результата может быть выполнено как:

Для val = 6.825 , результат, 6.83 как и ожидалось.

Ибо val = 6.824999 результат есть 6.82 . Здесь предполагается, что в результате расчета точно 6.824999 и 7-е десятичное место равно нулю.

Ибо val = 6.8249999 результат есть 6.83 . В 9 этом случае седьмое десятичное место приводит к тому, что Round(val,6) функция дает ожидаемый результат. В этом случае может быть любое количество конечных 9 s.

Ибо val = 6.824999499999 результат есть 6.83 . Округление до восьмого десятичного знака в качестве первого шага, т. Round(val,8) Е. Учитывает один неприятный случай, когда вычисляемый результат с плавающей запятой вычисляется 6.8249995 , но внутренне представляется как 6.824999499999. .

Наконец, пример из вопроса . val = 37.777779 приводит к 37.78 .

Этот подход может быть далее обобщен как:

где N - точность, которая должна поддерживаться для всех промежуточных вычислений для чисел с плавающей запятой / двойников. Это работает и на отрицательных значениях. Я не знаю, является ли этот подход математически правильным для всех возможностей.

В языке C++ при определении переменных необходимо указать их тип, причём в дальнейшем тип менять нельзя.

Для числовых переменных распространёнными типами являются int, short, long, float и double.

К примеру, переменная с типом данных float — это число с плавающей точкой, для хранения которого используется 4 байта, а это 6-9 значимых цифр, обычно 7.

А переменная с типом данных double — это число с плавающей точкой, для хранения которого используется 8 байт, а это примерно 15-18 значимых цифр, обычно 16.

Зная это, рассмотрим следующий простейший код — для его выполнения, сохраните код в файл test.cpp:

Теперь скомпилируйте его:

Результат выполнения очень необычен:


Число 230.4732 обрезано до 230.473 — потерян одна цифра после запятой. А в числе типа double, значение которого 30949.12345678, обрезалось до 30949.1 — то есть вместо предполагаемых 15-18 значимых цифр получено только 6…

Отсюда возникает вопрос, почему в числе типа double можно использовать только 6 значимых цифр?

На самом деле, число double d содержит все цифры после запятой, которые присвоены этой переменной — всё дело в том, как выполняется проверка числа. У метода cout имеются свои настройки по умолчанию для вывода и форматирования чисел — если в числе больше 6 разрядов, то обрезаются цифры после запятой, если до запятой также больше 6 цифр, то используется научная запись числа, например 1.23457e+14.

Во-вторых нужно использовать std::setprecision(n), где n — это новая величина точности.

При использовании в выражении out << setprecision(n) или in >> setprecision(n) устанавливает для параметра точности потока out или in значение ровное n.

Отредактирует код нашей программы:

Заново скомпилируем и выполним его. Результат:

Именно этот результат мы и ожидали:


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

Читайте также: