Что следующим является нормализованное число с плавающей точкой после того, как (прежде чем) нормализованным числом с плавающей точкой f?

Да это - проблема. Но проблема может быть решена с помощью рекордных свойств:

type
  TRec = record
  private
    FA : integer;
    FB : string;
    procedure SetA(const Value: Integer);
    procedure SetB(const Value: string);
  public
    property A: Integer read FA write SetA;
    property B: string read FB write SetB;
  end;

procedure TRec.SetA(const Value: Integer);
begin
  FA := Value;
end;

procedure TRec.SetB(const Value: string);
begin
  FB := Value;
end;

TForm1 = class(TForm)
  Button1: TButton;
  procedure Button1Click(Sender: TObject);
private
  FRec : TRec;
public
  property Rec : TRec read FRec write FRec;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Rec.A := 21;
  Rec.B := 'Hi';
end;

Это компилирует и работает без проблемы.

6
задан pgast 26 August 2009 в 19:17
поделиться

4 ответа

Я не уверен, что вы имеете в виду под « нормализованное двойное число», но получение следующего представимого двойного числа выполняется с помощью nextafter () функция в большинстве стандартных математических библиотек C.

7
ответ дан 8 December 2019 в 13:47
поделиться

Как указано ниже, после небольшого исследования выясняется, что для положительных чисел с плавающей запятой в формате Intel IEEE754 размером n бит, которые < + бесконечность, обрабатывающая конкатенированную экспоненту и мантиссу как n-1-битовое целое число без знака, добавляя единицу, получаем следующее большее значение и (вычитая единицу, получаем следующее меньшее значение)

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

1
ответ дан 8 December 2019 в 13:47
поделиться

Утверждение в пункте 3) неверно. Если d немного меньше 2, то между d и (1 + eps) * d ровно 1 число с плавающей запятой. Вот программа, которая это демонстрирует:

#include <limits>
#include <iostream>

int main(int, char**)
{
  using namespace std;
  double d = 1.875;
  cout.precision(18);
  cout << "d = " << d << "\n";
  double d2 = (1.+numeric_limits<double>::epsilon())*d;
  cout << "d2 = " << d2 << "\n";
  double f = d + (d2-d)/2;
  cout << "f = " << f << "\n";
}

Причина в том, что (1 + eps) * 1,875 равно 1,875 + 1,875 * eps, что округляется до 1,875 + 2 * eps. Однако разница между последовательными числами с плавающей запятой между 1 и 2 составляет eps, поэтому существует одно число с плавающей запятой между 1,875 и 1,875 + 2 * eps, а именно 1,875 + eps.

Утверждение в пункте 2) верно, Я думаю. И Роберт Керн, вероятно, ответил на ваш настоящий вопрос.

3
ответ дан 8 December 2019 в 13:47
поделиться

Я думаю, это будет выпущен, когда он будет готов. Я не знаю даты релиза. Следите за блогом Riding Rails . Записки Райана удобны для отслеживания Edge Rails.

double x = 1.0;
uint64_t rep;
assert(sizeof x == sizeof rep);
memcpy(&rep, &x, sizeof x);
rep += 1;
memcpy(&x, &rep, sizeof x);

Это добавляет единицу к значимости x, работая с поразрядным представлением значения с плавающей запятой; если следующее значение находится в следующем бинаде, оно будет перенесено в показатель степени, вернув правильное значение. Если вы хотите, чтобы он работал с отрицательными значениями, вам нужно это настроить.

6
ответ дан 8 December 2019 в 13:47
поделиться
Другие вопросы по тегам:

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