Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 20:38 02 Jul 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : a small oddity in cint() and hex$

     Page 2 of 3    
Author Message
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2428
Posted: 10:18am 14 May 2020
Copy link to clipboard 
Print this post

can you extend it up past that range, up to say 16777220?


cheers,
rob   :-)
 
zeitfest
Guru

Joined: 31/07/2019
Location: Australia
Posts: 570
Posted: 12:13pm 14 May 2020
Copy link to clipboard 
Print this post

Not with 32 bit.

I am wondering about that situation. I tend to think,  a system should prevent an integer being generated if it will express more precision than the original data (float) can provide, or flag it somehow. My distant memories of the pic processors recall some arithmetic flags in the status registers (?) for those things (?).
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4032
Posted: 06:39am 15 May 2020
Copy link to clipboard 
Print this post

  robert.rozee said  can you extend it up past that range, up to say 16777220?


cheers,
rob   :-)


It gets awkward, because the obvious FOR loop (adding 1 on each loop and testing for the limit) loops forever.  That's because adding 1 actually adds zero now that you've hit the max.

If you just assign a constant then you rely on what the compiler/code generator turns that into.

I see:
trying to use 16777217 actually uses 16777216
trying to use 16777218 actually uses 16777218
trying to use 16777219 actually uses 16777220
(they carry on in steps of 2)

The -ves are the same (with minus sign).

This is C and it has fairly well defined behaviour (hampered by the fact floating point  is what it is).

John
Edited 2020-05-15 16:41 by JohnS
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2428
Posted: 12:59pm 15 May 2020
Copy link to clipboard 
Print this post

changing both occurrences of this line:

DO WHILE ( i < 4 )

to this:

DO WHILE ( i < 12 )

will achieve the desired result; based upon the result i can deduce what is most likely to be happening.


cheers,
rob   :-)
 
zeitfest
Guru

Joined: 31/07/2019
Location: Australia
Posts: 570
Posted: 01:47pm 15 May 2020
Copy link to clipboard 
Print this post

What does MMBasic do  up to say 16777220?

I am a bit surprised the Pascal jumped the 09 figure.

I am wondering if the different sources of C libraries show a difference. My (old) ANSI C book does not define the behaviour in that situation, probably IEEE does (?)

In general using single precision to yield the larger range of integers would be regarded as an unfavorable design, even if C lets it happen. Using double precision works (f77/C), I did not build in a trap for the single-precision use outside its bounds, it was intended but I lost interest

     PROGRAM z
C
     DOUBLE x
...
...

16777214.00000000 16777214
16777215.00000000 16777215
16777216.00000000 16777216
16777217.00000000 16777217
16777218.00000000 16777218
16777219.00000000 16777219
16777220.00000000 16777220
16777221.00000000 16777221
16777222.00000000 16777222
-16777214.00000000 -16777214
-16777215.00000000 -16777215
-16777216.00000000 -16777216
-16777217.00000000 -16777217
-16777218.00000000 -16777218
-16777219.00000000 -16777219
-16777220.00000000 -16777220
-16777221.00000000 -16777221
-16777222.00000000 -16777222
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4032
Posted: 02:00pm 15 May 2020
Copy link to clipboard 
Print this post

C does what you'd expect, if you think it through.

It can easily handle the range but not the precision.  So as you increase the magnitude more and more it does the right thing - approximates.

(Internally, as you go past the range which can be represented the exponent is altered by one, effectively shifting the mantissa right by one bit, and that's why half the numbers in the new part of the range get rounded/truncated - what would have been the bottom bit in the mantissa gets lost as there's no room for it.)

The same would happen with a double precision, just a much bigger range.

I don't have a C standard conveniently to hand but you can be sure this is defined behaviour.  Note that we're not doing anything that ought to cause an error (e.g. we're not causing overflow) - in any floating point system as far as I know, and not in IEEE 754 I am fairly sure but it's not the most easily grasped standard.

John
Edited 2020-05-16 00:06 by JohnS
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2428
Posted: 02:39pm 15 May 2020
Copy link to clipboard 
Print this post

  zeitfest said  What does MMBasic do  up to say 16777220?
DOUBLE x


i probably wasn't clear enough. please try with the following lines:

REAL x

and
DO WHILE ( i < 12 )


as it stands, running on an MX170, MMbasic does a double-step from 0x800001 up to 0xFFFFFF, and for values beyond this stops stepping.

with the proposed change, it should produce the correct results up to 0xFFFFFF, and from 0x1000000 stop stepping - adding 1 will produce no increment as 1 is below the level of granularity. i've just checked this behaviour with fpc (pascal).


cheers,
rob   :-)
Edited 2020-05-16 00:40 by robert.rozee
 
zeitfest
Guru

Joined: 31/07/2019
Location: Australia
Posts: 570
Posted: 03:18am 16 May 2020
Copy link to clipboard 
Print this post

It is as you suggest,  adding 1 after the 16777216 produces no increment, adding 2 increments ok, presumably until the next watershed etc

16777214.000000 16777214
16777215.000000 16777215
16777216.000000 16777216
16777216.000000 16777216
16777216.000000 16777216

...


We are in good company .. java ..

public class Main {

   public static void main(String[] args) {
      float fval = 16777217.0f ;
       int val ;
       val = (int) fval ;
       System.out.println(val);

 }

}

16777216


although if I don't force the float it does gripe (ed) as it uses double and tries to then convert  ..

public class Main {

   public static void main(String[] args) {
      float fval = 16777215.0 ;
       int val ;
       val = (int) fval ;
       System.out.println(val);

 }

}

Main.java:8: error: incompatible types: possible lossy conversion from double to float
      float fval = 16777215.0 ;


I am wondering what say C on raspberry pi does.
Edited 2020-05-16 13:26 by zeitfest
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4032
Posted: 06:20am 16 May 2020
Copy link to clipboard 
Print this post

It'll depend on the code and which compiler warnings are enabled.

As I just wanted to find the range I used straightforward code and didn't bother with warnings.

Essentially,
float f;
...
f = 16777216.0f;
then print f.

The above pretty much prevents warnings as I've told the compiler to assign a float to a float.

I can mess about leaving off the trailing f (thus getting a double) and enabling warnings but TBH I can't see why because if writing numerically important code you have to understand this stuff and do proper error analysis.

John
Edited 2020-05-16 16:22 by JohnS
 
zeitfest
Guru

Joined: 31/07/2019
Location: Australia
Posts: 570
Posted: 08:26am 17 May 2020
Copy link to clipboard 
Print this post

I am relieved my little f77 interpreter handles it OK.
Shepherding half-a-dozen or so datatypes through parsing via a shunting-yard treatment and calculation etc while retaining canonical accuracy is not code I want to revisit !! At one stage I could set it to reject any math that tried to mix 32 bit and 64 bit floating point....that was just too exasperating to be practical.

But it raises a question, ie, if hardware A is always 32 bit and hardware B is always 64 bit, and the interpreter/language used is arbitrarily handling values as integers or floating point, I think the same user code may run differently on the two platforms eg if a floating point value is compared to an integer and so on. (?)
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4032
Posted: 12:27pm 17 May 2020
Copy link to clipboard 
Print this post

I suspect f77 will in effect say (C does), because ANSI/ISO standards tend to cover such things and have done for decades.

Yes code can behave differently if it fails to be written with the behaviours of floating point in mind.  (This isn't an issue for most software, in reality.)

I suspect your specific example is not allowed, but your general point is true :)

(C specifies in probably more detail than most ever want to read what happens in many (I hope all) of the awkward cases.  It's not particularly easy to write 100% correct code using floating point, but the hardware does what the hardware does and all the software can do is its best despite that.)

Things were much more painful when machine A had 6-bit characters (inevitably not ASCII), 24-bit integers, 48-bit floating point, and machine B had 8-bit characters, 60-bit floating point and I can't recall what size integers were.  Oh, and machine C had 8-bit chars using EBCDIC, 32-bit integers, and so on.

It didn't help that some were little endian, some big endian and the occasional (but common) were mixed endian...

John
 
panky

Guru

Joined: 02/10/2012
Location: Australia
Posts: 1114
Posted: 12:46am 18 May 2020
Copy link to clipboard 
Print this post

I am following this thread with interest but am struggling to understand the actual detail of the issue under discussion. Would it be possible to distill the main thrust down into simple language for those of us who are interested (and fascinated by the deep knowledge of those posting)?

I really enjoy these semi theoretical discussions, thanks.

Doug.
... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it!
 
Chopperp

Guru

Joined: 03/01/2018
Location: Australia
Posts: 1094
Posted: 02:37am 18 May 2020
Copy link to clipboard 
Print this post

I'm with Doug....
ChopperP
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6266
Posted: 03:48am 18 May 2020
Copy link to clipboard 
Print this post

I posted a reply but something happened so here it is again:

Floating point numbers always seem to cause much discussion.
The only way we can represent really big numbers with 32 bits is to round them off once they get too many digits.

Later 'mites use 64bit floating point so we can have a lot more cash in the bank before the accounts don't balance.

With 32bit floating point the rounding occurs at 2^24 or 16,777,216

To test the device I am programming on I use this one liner:
x! = 50000000000 : if (x! = 50000000001)then print "Single" else print "Double"\n

If X = X+1 we know we have a problem, but only if we expect ridiculous precision.

Rob noticed that the precision dropped of on micromites at 2^23 or 8,388,608 and decided to dig around and find out why.
He succeeded and MMBasic will be better for it.

Jim
VK7JH
MMedit
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4032
Posted: 06:34am 18 May 2020
Copy link to clipboard 
Print this post

In short, MMBasic (some/all versions) have one or more bugs.

The computer can cope with all the integers (whole numbers) in the inclusive range -16777216 to 16777216 but MMBasic fails for some of them (a currently unknown number of them, I think).

It appears to depend on which function or operation your code does.  E.g. perhaps CINT, STR$ but I don't know which.

I expect arithmetic operations (+ - * /) work fine, not sure about conversions.

edit: although it needs fixing, all that happens looks to be a slight loss of precision (in floating point only, and in certain numbers) and that is very unlikely to affect MMBasic programs generally.

John
Edited 2020-05-18 17:14 by JohnS
 
zeitfest
Guru

Joined: 31/07/2019
Location: Australia
Posts: 570
Posted: 07:34pm 19 May 2020
Copy link to clipboard 
Print this post

I think those are reasonable ways of describing it.

However I would add add a caveat, ie if a problem like that surfaces it implies breadth-of-system accuracy programming and testing has been incomplete or failed, over several versions. If there is even a trivial difference (ed -in results) between the Extreme and CMM2, there is not supposed to be. These things are not a walk in the park.

Commiserations guys.. a real slog I know.

(exit thread)
Edited 2020-05-20 05:42 by zeitfest
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4032
Posted: 09:13am 20 May 2020
Copy link to clipboard 
Print this post

I'm not sure I understood that!

Obviously, Rob's found a bug.

But it probably affects no actual programs (other than whatever Rob was doing).

Regardless of this bug, using any floating point generally means you're happy with slight inaccuracy - it certainly needs to mean that! - and have figured out any awkward cases where it could bite you.  It also needs to mean you have figured that out!

All this bug does is make that marginally more important, as it causes a slight loss of precision in cases where it should not cause such slight loss.

John
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2170
Posted: 07:05am 26 Jun 2020
Copy link to clipboard 
Print this post

  JohnS said  happy with slight inaccuracy


happy? Not really. Stuck with it? undoubtedly

I couldn't write a universal system that would deal with it all. I have written systems to specifically avoid problems like this but they all have ceilings. Damn you universe!    

Often times,  the rounding errors are a product of the radix (base number) used - I had a discussion a few years back with someone that mathematically "proved" 9.99999... was equal to 10. I vaguely remember a maths teacher doing the same to show 1=2 or something like that. I tried to point out that it all depends on the radix and illustrated with 10/3 not possible to do precisely in radix 10, but perfect in radix 30... it was lost and degenerated into ad-hominem abuse from which I retired.
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4032
Posted: 08:42am 26 Jun 2020
Copy link to clipboard 
Print this post

This bug is fixable, but may well be extremely low priority as it perhaps affects no actual programs?

One for Geoff.

(The issues with floating point can only be fully fixed by not using it.  Otherwise just write code that copes.)

John
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2170
Posted: 09:00am 26 Jun 2020
Copy link to clipboard 
Print this post

just to qualify, having read my post back, when I said "stuck with it" I was referring to the inadequacies of our number systems, not any bug in the firmware
 
     Page 2 of 3    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025