这个 C++ 会吗?将 PDP-11 浮点数转换为 IEEE?

发布于 2024-08-20 19:44:20 字数 923 浏览 2 评论 0原文

我正在维护一个程序,该程序从 PDP-11(模拟!)程序中获取数据并将其放入基于 Windows 的现代系统中。我们遇到一些数据值报告为“1.#QNAN”和“1.#QNB”的问题。客户最近透露,PDP-11 程序中的“坏”值由 2 个 16 位字表示,其中除第一个位外的所有位均已设置。我认为正是当我们尝试将它们转换为 IEEE 浮点数时,我们才会遇到错误。

我发现下面的代码用于将 PDP-11 值转换为 IEEE。我不太了解浮点表示的复杂性,但这对我来说似乎有点简单!这真的能可靠地将 PDP-11 浮点数转换为 IEEE 吗?

// ---------------------------------------------------------------- cnvPDPfloat
// CNVPDPFLOAT
// ----------------------------------------------------------------------------
//
// Converts PDP11 float (two 16-bit words) into IEEE float
//
//  PDP11 and IEEE floats have same layout so can be mapped onto eachother.
//  But PDP11 exponent must have 2 subtracted for IEEE. Or just divide by 4.
//
float cnvPDPfloat( PDP11Float input )
{
 union
 {
  unsigned long pdp11;
  float   ieee;
 } uFloat;

 uFloat.pdp11 = (input.word[0] << 16) + input.word[1];

 return (uFloat.ieee / (float) 4.0);
}

——阿利斯泰尔。

I am maintaining a program that takes data from a PDP-11 (emulated!) program and puts it into a modern Windows-based system. We are having problems with some of the data values being reported as "1.#QNAN" and also "1.#QNB". The customer has recently revealed that 'bad' values in the PDP-11 program are represented by 2 16-bit words with all the bits set except the first. I think that it is when we try to convert these to IEEE floats that we are getting the errors.

I have found the code below that is used for converting the PDP-11 values to IEEE. I am not very in touch with the intricacies of floating point representations but this seems a bit simple to me! Would this really reliably convert PDP-11 floats to IEEE?

// ---------------------------------------------------------------- cnvPDPfloat
// CNVPDPFLOAT
// ----------------------------------------------------------------------------
//
// Converts PDP11 float (two 16-bit words) into IEEE float
//
//  PDP11 and IEEE floats have same layout so can be mapped onto eachother.
//  But PDP11 exponent must have 2 subtracted for IEEE. Or just divide by 4.
//
float cnvPDPfloat( PDP11Float input )
{
 union
 {
  unsigned long pdp11;
  float   ieee;
 } uFloat;

 uFloat.pdp11 = (input.word[0] << 16) + input.word[1];

 return (uFloat.ieee / (float) 4.0);
}

--- Alistair.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

土豪 2024-08-27 19:44:20

该代码不会检查未定义值干净零脏零,但除以4(在其他答案中讨论)是好的。 OP 可能知道这一点,因为他们会发现结果是否总是错误的。
今天指数偏差也让我感到困惑,所以我将引用我刚刚在这份精美文档中读到的内容: 带有隐藏位的二进制浮点数

首先,隐藏位被赋予另一个位置。 IEEE 假设该位
在小数周期之前,数字假设它紧随其后
那个时期。根据 IEEE 的规定,尾数的可见部分
('visman') 在句号之后立即开始,同时根据
数字它从隐藏位后面开始。因此取值范围为
总尾数为:

<前><代码>IEEE:1.0 =< (1.visman) < 2.0
数字:0.5=< (0.1维斯曼)< 1.0

其次,指数表示法中的过度偏差有所不同。 [按 1 ...]

这两种效果共同构成了 IEEE-float 中的位模式
表示一个数字,其大小是同位值的四倍
Digital-float 中的模式代表。

这也解释了为什么一些参考文献指出 IEEE 偏差为 126。

The code doesn't check for undefined value, clean-zero and dirty-zero, but dividing by 4, discussed in other answers, is good. The OP probably knows it because they would spot if the result was always wrong.
The exponent bias also confused me today, so I'll quote what I've just read in this fine document: Binary floats with hidden bit:

At first the hidden bit is given another position. IEEE assumes this bit
before the fractional period and Digital assumes it immediately after
that period. According to IEEE the visible part of the mantissa
('visman') starts immediately after the period, whilst according to
Digital it starts behind the hidden bit. Thus the value range of the
total mantissa is:

IEEE:      1.0 =<  (1.visman)  < 2.0
Digital:   0.5 =< (0.1 visman) < 1.0

At second the excess-biases in the notation of the exponent differ. [by 1 ...]

Both effects together make that the bit pattern in an IEEE- float
represents a number four times in size of the value the same bit
pattern in a Digital-float stands for.

This also explains why some references state that IEEE bias is 126.

凝望流年 2024-08-27 19:44:20

此页面中,PDP-11 格式与IEEE-754 浮点格式,不同之处在于 PDP-11 中指数偏置 128,而 IEEE-754 中指数偏置 127。因此,您需要除以 2.0,而不是 4.0。这不考虑 NaN 和无穷大,但从我的谷歌搜索来看,看起来 PDP-11 没有这些。

您还会遇到溢出问题。 PDP 格式较早溢出,但我假设这没关系,因为一旦数字已经溢出,您就无法真正执行任何操作。

From this page, the PDP-11 format is identical to IEEE-754 floating-point format except that the exponent is biased by 128 in PDP-11, whereas it is biased by 127 in IEEE-754. So, you need to divide by 2.0 and not 4.0. This doesn't take care of NaNs and infinities, but from my google searches, looks like PDP-11 didn't have those.

You will also have issues with overflow. The PDP format overflows earlier, but I am assuming that is OK since you can't really do anything once a number has already overflown.

分开我的手 2024-08-27 19:44:20

PDP-11 使用混合字节序表示浮点数。 这部分代码

uFloat.pdp11 = (input.word[0] << 16) + input.word[1];

因此,如果您的数据在获取之前尚未进行字交换,则

是正确的。本文档提供了许多不同浮点格式表示的详细信息 http://www.quadibloc .com/comp/cp0201.htm

它说 t PDP-11/VAX 使用了超过 128 的指数表示法。而 IEEE 754 使用多余的 126 表示法,因此如果正确的话,除以 4 似乎是调整指数的正确方法。

但是,维基百科表示 IEEE 754 的指数偏差是 127,而不是 126。因此,上述文档要么使用了奇怪的符号,要么是不正确的。您可能需要除以 2 而不是除以 4。

The PDP-11 used a mixed-endian representation for floating point numbers. so this part of the code

uFloat.pdp11 = (input.word[0] << 16) + input.word[1];

is correct if your data hasn't already been word-swapped before you get it.

This document gives details of the representation for a lot of different floating point formats http://www.quadibloc.com/comp/cp0201.htm

It says that t PDP-11/VAX used excess 128 notation for the exponent. whereas IEEE 754 uses excess 126 notation, so if it is correct, dividing by 4 seems to be the correct way to adjust the exponent.

However, Wikipedia says that the exponent bias for IEEE 754 is 127, not 126. So either the above document is using a strange notation, or it is incorrect. It's possible that you need to divide by 2 rather than by 4.

离不开的别离 2024-08-27 19:44:20

除了 NaN 和 Inf 之外,您还可能会遇到非正规值转换的问题。我不知道 PDP-11 是否支持这些,但 IEEE 754 规定,当指数字段为 0 时,数字是非正规的,这实际上意味着尾数字段中隐含的前导 1 变为 0。这样就有了当数字减少时逐渐收敛到0。

@John - IEEE 754 标准规定指数偏差是 127,而不是 126。Wiki 是正确的,其他参考是错误的。因此,该比率将为 2.0。

In addition to NaN and Inf, you may also have problems with conversion of denormal values. I don't know if PDP-11 supports these, but IEEE 754 states that when the exponent field is 0, then the numbers are denormals, effectively meaning that the implied leading 1 in the mantissa field becomes a 0. This way there is a gradual convergence to 0 when numbers are decreasing.

@John - The IEEE 754 standard states that the exponent bias is 127, not 126. Wiki is right and the other reference is wrong. So, the ratio would be 2.0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文