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 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: 64-bit unsigned integer? Date: Sun, 25 Feb 2018 14:23:17 +0100 Organization: Aioe.org NNTP Server Message-ID: References: <63f986fd-662a-47e7-adf9-5fddc243ac45@googlegroups.com> NNTP-Posting-Host: b3/KWLDSh2Q785SrqKUcjA.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 Content-Language: en-US X-Notice: Filtered by postfilter v. 0.8.3 Xref: reader02.eternal-september.org comp.lang.ada:50635 Date: 2018-02-25T14:23:17+01:00 List-Id: On 2018-02-25 13:54, MM wrote: > On Sunday, 25 February 2018 12:42:00 UTC, Dmitry Kazakov wrote: >> On 2018-02-25 13:30, MM wrote: >>> type u64 is range 0 .. 2**64-1; -- this fails with "integer type definition bounds out of range". >> >> This is the right method alas not supported by the architecture of the >> machine you have. > > Damn. Its a 64-bit CPU; I would have thought that a Carry Or Overflow > bit in the processor would have done the trick? > >>> Is there a way to do it so can get an unsigned integer that will raise an >>> exception if it overflows? >> >> You must implement it yourself, e.g. on top of a modular or integer >> type, or use an arbitrary length integer arithmetic package. There exist >> a few in Ada. > > I don't want to go the BigNum route - too heavyweight. Implementing it > efficiently myself may require access to the processor's condition code > registers, so this feels like an assembly language approach? Why, it is straightforward because you have no negatives. Something like this: package Unsigneds_64 is type u64 is private; function "+" (Left, Right : u64) return u64; function "-" (Left, Right : u64) return u64; function "*" (Left, Right : u64) return u64; function "/" (Left, Right : u64) return u64; private use Interfaces; type u64 is new Unsigned_64; end Unsigneds_64; package body Unsigneds_64 is function "+" (Left, Right : u64) return u64 is Result : constant u64 := u64 (Unsigned_64 (Left) + Unsigned_64 (Right)); begin if Result - Left /= Right then raise Constraint_Error; else return Result; end if; end "+"; function "-" (Left, Right : u64) return u64 is begin if Left < Right then raise Constraint_Error; else return u64 (Unsigned_64 (Left) - Unsigned_64 (Right)); end if; end "-"; function "*" (Left, Right : u64) return u64 is begin if Left = 0 then return 0; else declare Result : constant u64 := u64 (Unsigned_64 (Left) * Unsigned_64 (Right)); begin if Result / Left /= Right then raise Constraint_Error; else return Result; end if; end; end if; end "*"; function "/" (Left, Right : u64) return u64 is begin return u64 (Unsigned_64 (Left) / Unsigned_64 (Right)); end "/"; end Unsigneds_64; -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de