Closed evanescente-ondine closed 3 weeks ago
You don't need to convert to a floating-point type. Converting a real value (including a fixed-point value) to an integer type rounds to the nearest integer (away from zero if exactly halfway between two integers), RM 4.6(33). Presumably your types for "dollars" and "cents" are integer types, so just a type conversion like
D : Dollars_Type := Dollars_Type (M);
where M is of the fixed-point "currency" type will give you the number of dollars, but rounded so if D > M you have to subtract one from D (here assuming that M is non-negative). The number of cents can then be computed from M-D, multiplied by 100. For the comparison and subtraction you do need to convert D to the currency type, of course.
I see, I wish I had read this solution before. There should be definitely be a "Guide To Ada Numerics" dealing with all the issues of representation, bit order, floating point arithmetics etc, with exemples, somewhere. I don't understand the attributes at all, too technical. That said, isn't it still a round-away too, to have to substract depending on the sign ? Even though I can still take the absolute value before.My question is rather, is there a more efficient, machine way to tell apart integral from decimal part, something the compiler could know or work out better ? At least in decimal types.
Did you consider the package Ada.Decimal? You might be interested by my presentation at FOSDEM: https://archive.fosdem.org/2022/schedule/event/ada_numerics_model/ or my paper in the Ada User Journal: https://adalog.fr/publicat/Rosen_Ada_Numerics_Model-AUJ43.pdf
Even though I can still take the absolute value before.My question is rather, is there a more efficient, machine way to tell apart integral from decimal part, something the compiler could know or work out better ? At least in decimal types.
There are many "nice to have" things that could be added to Ada, but those do not have a high priority in the language maintenance and evolution process. The package Ada.Decimal (which I did not remember, not having had occasion to use it after it was introduced) covers this issue, I think. Still, I would not object to the addition of a 'Truncation attribute for fixed-point types.
The 2022 Ada RM permits implementations to support all floating-point attributes on fixed-point types. See RM 4.1.4(13/5 - 15/5):
An implementation may extend the definition of a language-defined attribute by accepting uses of that attribute that would otherwise be illegal in the following cases: • in order to support compatibility with a previous edition of of this Reference Manual; or • in the case of a language-defined attribute whose prefix is required by this document to be a floating point subtype, an implementation may accept an attribute_reference whose prefix is a fixed point subtype; the semantics of such an attribute_reference are implementation defined.
But "permits" is the last thing users like to read. I get that many attributes relates to representation issues so are impacted by choices in implementation, but is there a reason why 'Floor, 'Celling, 'Rounding, 'Unbiased_Rounding, 'Machine_Rounding, 'Truncation or 'Copy_Sign not to apply by default to fixed points or decimal types ? Their definition seem quite independent from the implementation. Seems like floating points have such a richness of tools to them, but decimals are like the newest, anemic little brother.
I agree that at some point we should standardize these attributes. Allowing the permission for implementations to support them was kind of a last-minute quick fix, since without that permission implementations would have to use some other name for the fixed-point attributes, since the Ada RM disallows implementations to reuse existing attribute names for different purposes. GNAT, for example, already supports 'Round on (ordinary) fixed-point types.
But you are certainly correct that decimal fixed-point types are not as well supported as other sorts of types, in part because they are not as relevant to Ada's typical past primary application area, namely real-time embedded systems.
AdaCore is quite responsive to paying customers, and GNAT is open source, so there are possibilities to improve things if you have enough energy and/or resources ...
I get that many attributes relates to representation issues so are impacted by choices in implementation, but is there a reason why 'Floor, 'Ceiling, 'Rounding, 'Unbiased_Rounding, 'Machine_Rounding, 'Truncation or 'Copy_Sign not to apply by default to fixed points or decimal types ?
Well, yes, actually.
Their definition seem quite independent from the implementation.
True, but they don't make sense for all fixed point types (they do make sense for all decimal types).
Anyway, we long ago addressed this issue in Ada post-Ada22; AI22-0057-1 was approved more than a year ago. It adds these attributes for most fixed point types (but not those that do not have integral values). See the AI for details.
It's valuable, of course, to hear that these issues matter to real users, but otherwise this discussion is essentially noise. We have no control over when these AIs will get implemented in your favorite compiler, of course, and that is probably the thing that matters most.
Randy.
Here is a link to AI22-0057-1: https://docs.google.com/document/d/1Q3k9FSMea3HpG5jdhm4c2tTIk49RJiUjxmSjsWoi50c -Tuck
Or you can of course use Ada-Auth.org (should be working now after the recent troubles): http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai22s/ai22-0057.html
You can always find AIs from the summary page: http://www.ada-auth.org/AI22-SUMMARY.html or the voting index: http://www.ada-auth.org/AI22-VOTING.html
Randy.
From: S. Tucker Taft @.*** Sent: Wednesday, October 09, 2024 8:16 PM To: Ada-Rapporteur-Group/User-Community-Input Cc: ARG-Editor; Comment Subject: Re: [Ada-Rapporteur-Group/User-Community-Input] 'Truncation for binary and decimal fixed point types (Issue #108)
Here is a link to AI22-0057-1: https://docs.google.com/document/d/1Q3k9FSMea3HpG5jdhm4c2tTIk49RJiUjxmSjsWoi 50c -Tuck
- Reply to this email directly, view https://github.com/Ada-Rapporteur-Group/User-Community-Input/issues/108#iss uecomment-2403704923 it on GitHub, or unsubscribe https://github.com/notifications/unsubscribe-auth/AT65YN7XO3LN6EQC4FW6HEDZ2 XIOZAVCNFSM6AAAAABPOXUCMCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIMBTG4YDI OJSGM . You are receiving this because you commented. https://github.com/notifications/beacon/AT65YN6LWTP3K7YXQ7ORYILZ2XIOZA5CNFS M6AAAAABPOXUCMCWGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTU PIWQFW.gif Message ID: @.***>
@evanescente-ondine I wish I saw this sooner, I created a currency library recently and solve the rounding problem for decimals in an interesting way if you're curious: https://github.com/AJ-Ianozi/Cashe/blob/main/src/cashe.ads https://github.com/AJ-Ianozi/Cashe/blob/main/src/cashe.adb
Hi, I'm just learning and I have had to write a Currency-type of package, so naturally I defined a decimal type. But I had to separate cents and dollars, meaning the fractional and integral parts. I searched the internet, and seemingly the only solution is to convert to a floating point and use 'Truncation (or 'Rounding). Beside being ugly, this seems to defeat the point of strong typing. It seems quite the dumbfounding lack in my opinion, considering all the extensive facilities put in Ada since the beginning to facilitate accounting work. We need a real fix urgently