From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,XPRIO autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,6cf602b7ea8a1df1,start X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-02-15 03:28:05 PST From: "Martin Dowie" Newsgroups: comp.lang.ada Subject: Floating point accuracy Date: Thu, 15 Feb 2001 11:27:43 -0000 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.50.4522.1200 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 NNTP-Posting-Host: sg2ntw48151.dsge.edinbr.gmav.gecm.com Message-ID: <3a8bbb84$1@pull.gecm.com> X-Trace: 15 Feb 2001 11:20:36 GMT, sg2ntw48151.dsge.edinbr.gmav.gecm.com Path: supernews.google.com!sn-xit-03!supernews.com!freenix!fr.clara.net!heighliner.fr.clara.net!grolier!btnet-peer0!btnet-feed5!btnet!newreader.ukcore.bt.net!pull.gecm.com!sg2ntw48151.dsge.edinbr.gmav.gecm.com Xref: supernews.google.com comp.lang.ada:5271 Date: 2001-02-15T11:27:43+00:00 List-Id: I'm trying to mimic 64-bit unsigned integers (that will represent nanoseconds) on a PowerPC (Green Hills target compiler for the PowerPC doesn't support 64 bit unsigned directly - unless you know differently!). I'm doing this by having a most sigificant and least significant 32bit unsigned in what will eventually be a private record and providing my own operators. However my routine to convert from microseconds to nanoseconds is puzzling me. I had always thought that a float declared a 'digits 15' would give me 15 significant digits of accuracy - I'm sure I'm only using up to 13 in these test, yet the last two results return the same values. clearly, I'm missing something... (on both WinNT/Gnat 3.13p & PPC/GreenHills/VxWorks5.4) Program = with Ada.Text_IO; use Ada.Text_IO; with Interfaces; procedure ns_test is type ns_type is record MS, LS : Interfaces.Unsigned_32; end record; type Real_15_Type is digits 15; function us_to_ns (Microseconds : Interfaces.Unsigned_32) return ns_Type is -- 16#FFFF_FFFF# = (2^32)-1 = 10#4_294_967_295#, which has 10 significant digits -- multiply by 1,000 (to convert to nanoseconds) => -- 10#4_294_967_295_000#, which has 13 significant digits => -- Real_15_Type has enough significant digits to represent the value in ns. -- Two_To_The_Thirty_Two : constant Real_15_Type := 2.0 ** 32; Float_ns : constant Real_15_Type := Real_15_Type (Microseconds) * 1_000.0; Float_MS : constant Real_15_Type := Real_15_Type'Floor (Float_ns / Two_To_The_Thirty_Two); MS : constant Real_15_Type := (Float_MS * Two_To_The_Thirty_Two); Float_LS : constant Real_15_Type := Float_ns - MS; begin Put_line ("ns = " & Real_15_Type'Image (Float_ns)); Put_line ("ms = " & Real_15_Type'Image (Float_MS)); Put_line ("MS = " & Real_15_Type'Image (MS)); Put_line ("ls = " & Real_15_Type'Image (Float_LS)); New_Line; return (MS => Interfaces.Unsigned_32 (Float_MS), LS => Interfaces.Unsigned_32 (Float_LS)); end us_to_ns; procedure display (value : ns_type) is begin put_line ("ms =>" & Interfaces.Unsigned_32'Image (Value.MS) & " ls =>" & Interfaces.Unsigned_32'Image (Value.LS)); end display; begin new_line; put_line ("test 0"); display (value => us_to_ns (microseconds => 0)); put_line ("test 1"); display (value => us_to_ns (microseconds => 1)); put_line ("test 1,000"); display (value => us_to_ns (microseconds => 1_000)); put_line ("test 16#0FFF_FFFF#"); display (value => us_to_ns (microseconds => 16#0FFF_FFFF#)); -- random mid-value put_line ("test 'Last - 1"); display (value => us_to_ns (microseconds => Interfaces.Unsigned_32'Pred (Interfaces.Unsigned_32'Last))); put_line ("test 'Last"); display (value => us_to_ns (microseconds => Interfaces.Unsigned_32'Last)); end ns_test; Results = -> test 0 ns = 0.00000000000000E+00 ms = 0.00000000000000E+00 MS = 0.00000000000000E+00 ls = 0.00000000000000E+00 ms => 0 ls => 0 test 1 ns = 1.00000000000000E+03 ms = 0.00000000000000E+00 MS = 0.00000000000000E+00 ls = 1.00000000000000E+03 ms => 0 ls => 1000 test 1,000 ns = 1.00000000000000E+06 ms = 0.00000000000000E+00 MS = 0.00000000000000E+00 ls = 1.00000000000000E+06 ms => 0 ls => 1000000 test 16#0FFF_FFFF# ns = 2.68435455000000E+11 ms = 6.20000000000000E+01 MS = 2.66287972352000E+11 ls = 2.14748264800000E+09 ms => 62 ls => 2147482648 test 'Last - 1 ns = 4.29496729400000E+12 ms = 9.99000000000000E+02 MS = 4.29067232870400E+12 ls = 4.29496529600000E+09 ms => 999 ls => 4294965296 test 'Last ns = 4.29496729500000E+12 ms = 9.99000000000000E+02 MS = 4.29067232870400E+12 ls = 4.29496629600000E+09 ms => 999 ls => 4294966296