我有一个例程,其目的是将浮点数编码为整数(然后将其放入字节流)。在此过程中,信息丢失。例程将输出切换为3.33的增量。
因此,0和3.33之间的差距有点奇怪,因为它不是零,而且它不是3.33。我决定(并非完全随意)任何非零浮动输入应该舍入到3.33(同样,3.34,应该达到6.66等)。
这一切都很好。代码如下:
function EncodeFloatingPoint (Value : Long_Float) return Integer is
Intermediate_Value : Integer;
Return_Value : Integer := 0;
begin
-- converts float into 3.33 increments
-- case 1, positive or zero
if (Value >= 0.0) then
--Ensures rounding away from zero
Intermediate_Value := Integer((Value * 100.0 + 332.99) / 333.0);
-- case 2, negative through -3.33 (up to, but not including zero)
else
-- Code omitted, is not problematic
end if;
Return_Value := Intermediate_Value;
return Return_Value;
end
当我在单元测试期间将值0.0
传递给我的代码时,会出现问题。单步执行时,转换的结果为3.33
,而不是预期的0.0
,我的单元测试失败。但是,当我转到GDB控制台并键入Print Integer((0.0 * 100.0 + 332.99) / 333.0)
时,结果为0(如果需要用0.0
代替值)。我可以确认Value打印到0.0。
可能发生什么事?有一种更简单的方法可以确保在将其转换回整数时从零开始舍入吗?
答案 0 :(得分:5)
您正在计算NetworkStream
,即约0.99997。从真实类型到整数类型的转换轮次[ARM 4.6(33)],所以你得到1.我认为你将它解释为3.33。你可能需要特殊情况零:
332.99 / 333.0
(注意,在“if”语句的条件下不需要括号。)
您可能还会发现if Value > Long_Float'Pred (0.0) and Value < Long_Float'Succ (0.0) then
return 0;
end if;
属性函数很有用。您应该熟悉ARM A.5.3中的所有浮点属性(实际上是ARM A中的所有标准库)。
您似乎正在使用3.33创建自己的定点类型。为什么不让语言为你做这件事?
'Remainder
答案 1 :(得分:2)
如果你查看Language Reference Manual,你会看到浮点类型有一个属性函数'Ceiling
,它产生的&#34;最小(最负)积分值大于或等于X&#34; (传递的参数)。
请尝试:Rounded := Floating_Point_Type'Ceiling (Not_Rounded)