Как установить целочисленную и дробную точность независимо друг от друга?

Я изучаю Fortran (со стандартом Fortran 2008) и хотел бы независимо установить точность целочисленной части и точность десятичной части для переменной real. Как мне это сделать?

Например, предположим, что я хотел бы объявить переменную real с точностью целой части, равной 3, и точностью дробной части, равной 8.

Примерный номер в приведенной выше спецификации будет, скажем, 123.12345678, но 1234.1234567 не будет удовлетворять данному требованию.


person anuvaramban    schedule 27.04.2017    source источник
comment
Для вещественных чисел Фортран определяет только числа с плавающей запятой. В такой модели мне непонятно, что вы имеете в виду под независимой точностью для целых и дробных частей. Можете пояснить на примере? [Конечно, вы можете использовать не внутренние вещи определенным образом.]   -  person francescalus    schedule 27.04.2017
comment
Вы имеете в виду десятичную часть и экспоненциальную часть (вместо целой части)?   -  person SteveES    schedule 27.04.2017
comment
@francescalus, я включил пример в описание   -  person anuvaramban    schedule 27.04.2017
comment
@SteveES Я добавил пример, пожалуйста, посмотрите на описание сейчас.   -  person anuvaramban    schedule 27.04.2017
comment
Почему вы хотите, чтобы ваши числа были отформатированы именно так? Что вы пытаетесь с ними сделать? Это для расчетов или для вывода?   -  person SteveES    schedule 27.04.2017
comment
@SteveES Я пытаюсь выполнить некоторые вычисления, для которых достаточно восьмизначной точности, но я также хочу, чтобы это было независимо от количества цифр в целой части.   -  person anuvaramban    schedule 27.04.2017
comment
Единственный реальный способ обойти это - определить ваши переменные с большей точностью, чем вам нужно в выводе, поэтому вы можете быть уверены, что ваша точность десятичной точки в конце будет такой, какая вам требуется.   -  person SteveES    schedule 27.04.2017


Ответы (2)


Действительные числа Fortran - это числа с плавающей запятой. Числа с плавающей запятой не сохраняют целую и десятичную части. Они хранят мантиссу и показатель степени.

Посмотрите, как работают числа с плавающей запятой http://en.wikipedia.org/wiki/Floating-point_arithmetic Обычно ваш процессор использует один формат с плавающей запятой, и вы не можете просто выбрать другой.

То, о чем вы просите, больше похоже на арифметику FIXED point, но современные процессоры и Fortran не поддерживают ее изначально. https://en.wikipedia.org/wiki/Fixed-point_arithmetic

Вы можете использовать их в различных библиотеках (даже, возможно, на Фортране) или языках, но они не являются нативными НАСТОЯЩИМИ. Вероятно, они реализованы программно, а не непосредственно в процессоре, и работают медленнее.

person Vladimir F    schedule 27.04.2017
comment
Спасибо за ваш ответ, у меня есть дополнение: сейчас я использую возвращаемое значение selected_real_kind (16), чтобы указать точность с помощью аргумента вида, но когда я распечатываю результат вычислений, он, кажется, использует, как если бы арифметика с фиксированной точкой. Например: поскольку я установил selected_real_kind(16), 3.14 ** 3.14 дает 36.3378388801746960712, тогда как 10.12 ** 10.12 дает 14873966072.8729692074, где я устанавливаю реальную переменную ar на 3.14 и 10.12 в последовательных запусках программы, которая просто выполняет ar ** - person anuvaramban; 27.04.2017
comment
Это недоразумение. И будьте осторожны, 10.12 — это действительная константа одинарной (по умолчанию) точности, если вы не объявите ее с определенным типом. См. stackoverflow.com/questions/6146005/ - person Vladimir F; 27.04.2017
comment
@anuvaramban Почему вы думаете, что это арифметика с фиксированной точкой? - person SteveES; 27.04.2017
comment
@SteveES, пожалуйста, посмотрите мой первый комментарий и результат, который я получил, общее количество цифр в обоих случаях одинаково, это верно, если я попытаюсь ввести любые другие числа. - person anuvaramban; 27.04.2017
comment
@VladimirF Сначала я назначаю его реальной переменной, поэтому я эффективно выполняю ar ** ar, где переменная ar = 10.12 и была объявлена ​​с ее параметром kind, как указано в возвращаемом значении функции selected_real_kind (16). - person anuvaramban; 27.04.2017
comment
Нет, это неправда!!! Пожалуйста, прочитайте stackoverflow.com/questions/6146005/ очень внимательно. Неважно, какой вид у ar. 10.12 - это ЕДИНСТВЕННАЯ точность! Также прочитайте stackoverflow.com/questions/42618704/, что проще. - person Vladimir F; 27.04.2017
comment
@anuvaramban Это именно то, что вы ожидаете от арифметики с плавающей запятой, которая сохраняет то же количество значащих цифр (в двоичном формате). Арифметика с фиксированной запятой теряет значительную точность цифр (конечно, с небольшими числами), но сохраняет точность десятичной точки. - person SteveES; 27.04.2017
comment
@anuvaramban Кроме того, помните, что формат числа на выводе не совпадает с его представлением внутренне - person SteveES; 27.04.2017
comment
@SteveES Спасибо! - person anuvaramban; 27.04.2017
comment
@VladimirF Спасибо! - person anuvaramban; 27.04.2017

В итоге я написал для этого функцию, чтобы использовать плавающие запятые с операторами .gt./.lt./.ge./.le./.eq. без фактического изменения плавающих запятых.

function PreciseInt(arg1, arg2) Result(PreciseInt)
  real*8     arg1       !Input variable to be converted
  integer*4  arg2       !Input # for desired precision to the right of the decimal
  integer*4  PreciseInt !Integer representing the real value with desired precision

  PreciseInt = idnint(arg1 * real(10**arg2))
end function
person Jtox    schedule 28.03.2019
comment
Пожалуйста, рассмотрите возможность использования кнопки {} для правильного форматирования кода. - person vmf91; 29.03.2019