Тип математики с плавающей запятой, которая может быть реализована на цифровом компьютере, обязательно использует приближение реальных чисел и операций над ними. (Стандартная версия стандартная работает до более чем пятидесяти страниц документации и имеет комитет для рассмотрения ее ошибок и дальнейшего уточнения.)
Это приближение представляет собой смесь приближений разного типа, каждый из которых можно либо игнорировать, либо тщательно учитывать из-за его конкретного способа отклонения от точности. Это также включает в себя ряд явных исключительных случаев как на уровне аппаратного обеспечения, так и на уровне программного обеспечения, которое большинство людей прогуливает прямо мимо, делая вид, что не замечает.
Если вам нужна бесконечная точность (например, вместо числа π одного из его более коротких резервных копий), вы должны написать или использовать символическую математическую программу.
Но если вы в порядке с идеей о том, что иногда математика с плавающей запятой нечеткая по значению и логике и ошибки могут быстро накапливаться, и вы можете написать свои требования и тесты для этого, тогда ваш код может часто проходить с помощью того, что находится в вашем FPU.
Кажется, что libc ++ следует этому требованию:
Каждая форматированная входная функция начинает выполнение, создавая объект класса
sentry
сnoskipws
(вторым) аргументомfalse
. Если часовой объект возвращаетtrue
, при преобразовании в значение типаbool
, эта функция пытается получить запрошенный вход. Если во время ввода выбрано исключение, тогдаios::badbit
включается312 в состоянии ошибки*this
. Если(exceptions()&badbit) != 0
, то исключение будет восстановлено. В любом случае отформатированная функция ввода уничтожает объект часовой. Если исключение не было выбрано, оно возвращает*this
.312) Это выполняется, не вызывая выброса
blockquote>ios::failure
.(цитируется по N4567 § 27.7.2.2.1 [istream.formatted.reqmts], но C ++ IS содержит идентичную формулировку. Акцент мой)
Я не знаю, действительно ли это означает «если
(exceptions()&badbit) == 0
, то входная функция должна но не исключение »
Сначала вы получите некоторую справочную информацию (каждый из них объясняется ниже в соответствующем заголовке, если вы хотите получить дополнительную информацию):
istream
s восстанавливал только / g10], когда ios_base::badbit
установлен в basic_istream::exceptions
ios_base::badbit
побито с нужным ios_base::iostate
в качестве обходного пути К сожалению, это обходное решение имеет побочный эффект также ретронирования всякий раз, когда ios_base::badbit
устанавливается независимо от ios_base::failbit
: http://en.cppreference.com/w/cpp/io/ios_base/iostate#The_badbit
Если вы ищете бросок, чтобы произойти только , когда ios_base::failbit
установлен, и вам нужно, чтобы это было одинаковое поведение в libc ++ и libstdc ++, вам нужно будет проверить ios_base::badbit
после каждой операции ввода, происходящей на istream
. Это должно выглядеть примерно так:
if((is.rdstate() & ios_base::failbit) != 0) throw ios_base::failure("basic_ios::clear");
Как отмечено cpplearner , вы даже не можете использовать basic_istream::fail
, у вас есть чтобы выполнить бит-тест теста istream
rdstate
. Но, честно говоря, это лишь добавляет немного сложности.
Что может сделать это монументальной задачей, так это то, в какой степени используется istream
. Широкое использование функции istream
можно было бы устранить с помощью вспомогательных функций, но использование istream_iterator
s или сложных перегрузок оператора извлечения быстро сделает ручную проверку этой необоснованной задачи.
Если вы окажетесь там я бы серьезно рассмотрел возможность обходного пути is.exceptions(ios_base::failbit | ios_base::badbit)
.
istream
s реконструировал только , когда ios_base::badbit
установлен в basic_istream::exceptions
] Вызов basic_istream::exceptions(istream::failbit)
установит маску, которую можно получить, вызвав basic_istream::exceptions()
, которая согласно 27.5.5.4 [iosstate.flags] / 11 стандарта:
Маска, которая определяет, какие элементы, установленные в
blockquote>rdstate()
, вызывают исключения.Это поддерживается в 27.7.2.2.3 [istream :: extractors] / 15 для неотформатированных методы вставки:
Если он не вставил никаких символов, потому что он поймал исключение, вызванное при извлечении символов из
blockquote>*this
иfailbit
включено вexceptions()
(27.5.5.4), тогда пойманное исключение отменяется.Однако для форматированного ввода это retrograded в 27.7.2.2.1 [istream.formatted.reqmts] / 1; требуя, чтобы бросок произошел только тогда, когда бит и маска и
ios_base::badbit
отличны от нуля:Если во время ввода выбрано исключение, то
blockquote>ios::badbit
включается в*this
. Если(exceptions()&badbit) != 0
, то исключение будет восстановлено.
libstdc ++ не соответствует этому требованию, но libc ++ делает
ios_base::failbit
должен быть установлен на нем соответствующийistream
для таких событий, как:Числовые, указательные и логические входные перегрузки
blockquote>basic_istream::operator>>
(технически, перегрузкиnum_get::get
, которые они вызывают), если вход не может быть анализируется как допустимое значение или если синтаксический анализ не подходит для целевого типа.[ Источник ]
Если используется только
ios_base::failbit
установлен на маскеbasic_istream::exceptions
', и происходит событие, в результате чего устанавливаетсяios_base::failbit
, например, извлечение недопустимого числа, как описано выше:
- В libstdc ++ исключение все еще отменено , которое не соответствует стандарту
- . В libc ++ это исключение не выбрано , что означает, что стандарт поддерживается
libc ++ делает недействительными ошибки, запрашивающие зеркалирование поведения libstdc ++
Теперь теперь недействителен ошибка для libc ++ для этой самой проблемы. Цитирование 27.7.2.1 [istream] / 4
Если одна из этих вызываемых функций выдает исключение, то, если явно не указано иначе, входная функция устанавливает
blockquote> < hr>badbit
в состояние ошибки. Если функцияbadbit
включена вexceptions()
, функция ввода отменяет исключение, не выполняя его действия, в противном случае он ничего не бросает и продолжает действовать так, как если бы вызванная функция вернула индикацию отказа.libc ++ proffers
ios_base::badbit
побито с нужнымios_base::iostate
в качестве обходного путиНаш собственный Говард Хиннант (который также является представителем libc ++, который invalidated связанная ошибка libc ++) предлагает в ответ на дубликат этого вопроса (а также в ошибке libc ++), что вы используете обходной путь:
is.exceptions(ios_base::failbit | ios_base::badbit);