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=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,6a77269912f77a70 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-10-28 10:10:12 PST Path: archiver1.google.com!news1.google.com!news2.google.com!fu-berlin.de!uni-berlin.de!82-43-33-75.cable.ubr01.croy.blueyonder.co.UK!not-for-mail From: Nick Roberts Newsgroups: comp.lang.ada Subject: Re: Why no 'Floor for fixed point types Date: Tue, 28 Oct 2003 18:10:06 +0000 Message-ID: References: <3F99FBE1.1030601@comcast.net> <3F9AFB67.5080401@comcast.net> NNTP-Posting-Host: 82-43-33-75.cable.ubr01.croy.blueyonder.co.uk (82.43.33.75) Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-Trace: news.uni-berlin.de 1067364609 36870271 82.43.33.75 (16 [25716]) User-Agent: Mozilla/5.0 (Windows; U; Win95; en-US; rv:1.5) Gecko/20031013 Thunderbird/0.3 X-Accept-Language: en-us, en In-Reply-To: <3F9AFB67.5080401@comcast.net> Xref: archiver1.google.com comp.lang.ada:1780 Date: 2003-10-28T18:10:06+00:00 List-Id: Robert I. Eachus wrote: >> No, Robert. Wrong! This function fails to do the 'floor' part of the >> calculation. The name 'Mantissa' is misleading, since the result will >> not be the mantissa (the decimal digits to the left of the decimal >> point) unless Tf'Small happens to be 1.0 (and I did explicitly exclude >> this case). > > First, the mantissa is not "the decimal digits to the left of the > decimal point." For a number written in scaled notation: 1.2345E6 it is > the part of the number before the exponent. Since in your program you > are attempting to remove the scaling from a fixed-point type, the name > Mantissa seemed appropriate. Change it if you wish. I'm sorry, you're right about the mantissa. In fact, in your example, I think the mantissa would strictly be 0.12345, and the exponent 7, but I wouldn't mind being set straight on this point. > But you didn't pay attention above. The compiler allows you to think > about fixed-point types as if they are real (non-integer) values. But > they are not implemented that way. Any compiler that uses > floating-point arithmetic to do fixed-point computations has a lot of > bugs in it. They just havent been found yet. (And I think it was ACVC > 1.4 that added a lot of tests which found such bugs.) Fixed point values > are represented as integers. I understand that fixed point types are intended to be represented as integers, and that most Ada implementations do so. I also thought the idea was that the Ada 95 standard was framed to permit other representations. I have heard that on some machines it makes sense to use the native floating-point representation (because the machine has sufficient support for operations on this representation). When you say 'bugs', I guess you mean 'inaccuracies'. I would honestly appreciate you saying a bit more on this subject (it is quite important to me, as a compiler writer!). I'm also not really sure as to the point you really making, Robert, so -- at the risk of trying your patience -- I'd appreciate any clarification you can make. > Their "actual" value is > the integer times a scale factor 'Small. If you divide a fixed point > number by its 'Small, you get an integer. Doing the arithmetic right > can be tricky in theory, but most compilers are smart enough to > recognize that all they need to do is nothing. That was why I advised > you to write it that way--compilers are sensitive to that special case: Well, from the point of view of the compiler I am writing, I would be grateful for more information on the tricky bits. >>> -- Of course, any decent compiler should be able to recognize this >>> -- special case and do nothing. If your compiler doesn't recognize this >>> -- you could rewrite Mantissa as an instance of Unchecked_Conversion. > >> Yuk! I would suggest you either put up with the redundant operation or >> get a new compiler. > > I assume that the Yuk! was about the reference to Unchecked_Conversion. Yes it was. Surely it is possible that there will be differences between the underlying integer an implementation uses for a fixed point type, and an apparently equivalent integer type. For example, the implementation may offset the value in the former. What works for one implementation is likely to be non-portable, and could suddenly fail in many other circumstances too. > But I think you didn't understand why it was there. I was not > encouraging anyone to write that way, but to use 'Small in an idiom the > compiler should recognize. I only mentioned the Unchecked_Conversion > possibility to help people recognize what is going on in this function: > NOTHING. It is a notation to tell the compiler to switch from treating > the value as having fixed-point type, and to instead look at the value > as an integer. Okay, I understand that, and that is part of what I was trying to achieve with the Scaled_Floor I suggested. The other part of what I was trying to achieve with this function was the 'floor' part, where the value is rounded down to the nearest 1/Tf'Small. I was suggesting this second part should be done using integer arithmetic (after conversion). Are you saying that this part should be done using fixed-point arithmetic? (I think you might be right.) >> Having declared: >> >> Scale: constant := 1/Temperature'Small; >> >> type Scaled_Temperature is >> range Temperature'First*Scale .. Temperature'Last*Scale; > > > At this point the compiler will give you an error message. Let's say we > fix it: > > type Scaled_Temperature is > range Integer(Temperature'First/Temperature'Small) > ..Integer(Temperature'Last/Temperature'Small); Oops! Well spotted. Possibly this mistake suggests that Scaled_Temperature should be a fixed point type, rather than an integer type (with delta 1.0). Do you agree? >> function Scaled_Floor (X: in Temperature) return Scaled_Temperature is >> subtype ST is Scaled_Temperature; >> begin >> return ST(X*Scale) - ST(X*Scale) mod ST(Scale); >> end; > > ...Now I understand the problem you think you are solving with this > code. With the fix above so it compiles, for lots of values of > Temperature'Small you will end up dividing by zero. Is that so? Could you please illustrate. Remember, I did specifically say that Tf'Delta is less than 1. > With other values > of Temperature'Small you will have overflows. So the range where your > method works is fairly small. Again, I'd appreciate more information about this. > For this particular problem though, > > Integer(Float'Floor(Float(X))); > > Should do what you want. But this begs the original question of this thread, doesn't it? Why doesn't Ada 95 provide the Floor attribute for fixed point types? I admit I never really answered this question, and it's a fair one, isn't it? Also, is the above formulation (which I think we can assume really would convert the value to a floating-point representation, and then use some kind of iterative approximation scheme to compute the floor value, and then convert to Integer) reasonably efficient? > (Or what you should want, or something like that.) Hehe. Of course, the trick is always to know what you need, rather than what you want. -- Nick Roberts