I'm happy to report that I've reduced the Apple II version down to 8,186 bytes! This version is the v0.3.2 tag on GitHub. There are a few bug fixes too, e.g., comparisons of negative numbers work correctly now.
My `ROUND` is not exactly the same as `INT(X+0.5)`; it's actually `INT(X+0.5*SGN(X))` which is either better or totally wrong. I need the `round` function in fp.s to implement `fexp` and `fsin`, and I optimized function dispatching so that BASIC functions that just wrap the floating point functions are almost free (in terms of space), so I was able to keep `ROUND`.
I'm still slower than Applesoft, but at least I'm not slower *and* larger.
More later on the other topics.
A contest to reduce code size
Re: A contest to reduce code size
Name it "CINT". That's how it is called elsewhere and saves a byte too.
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: A contest to reduce code size
In TRS-80 Level 2 BASIC it's called FIX, for an additional byte of savings.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!
Mike B. (about me) (learning how to github)
Mike B. (about me) (learning how to github)
Re: A contest to reduce code size
Floating point is (IMO) badly handled by many languages (and programmers!) It's hard to get right and harder to please everyone with your interpretation of right ...
In the C world we have floor(), ceil() and rint(). Floor truncates to the nearest integer down, ceil truncates to an integer up and rint is round to nearest integer. Or you can changing the rounding direction, decide to raise exceptions or not then there's round to even or not ... Sometimes it' a bit much.
So is floor (-1.5) -1 (rounding to zero) or -2 (rounding down) ?
I'm in the process of implementing some ieee754 floating point routines on a platform with no hardware FP and looking at various libraries and how they work while implementing my own. It seems the GNU routine in one library I have; "fix" is close to floor rounding to zero. And that's all it has - other operations have to be synthesized.
I'd really like to see an IEEE754 library for the 65C02/816 but it'll have to wait. A down-side is that it's "only" 4 bytes rather than 5, but the reality is that we rarely need more precision than what that affords. Everything more is basically peacocking in our little Basic world.... However the advantages to a 5-byte format is the ease of manipulating a 4-byte mantissa - especially if you already have good, fast routines to manipulate 32-bit quantities (in e.g. BBC Basic). IEEE format needs unpacking and re-packing for each operation unless you have the means to fuse operations such as a multiply and add where you could keep them internally in their unpacked format. Now - some "classic" minicomputer Basics do have matrix operations, but they're rare in the microcomputer world.
-Gordon
In the C world we have floor(), ceil() and rint(). Floor truncates to the nearest integer down, ceil truncates to an integer up and rint is round to nearest integer. Or you can changing the rounding direction, decide to raise exceptions or not then there's round to even or not ... Sometimes it' a bit much.
So is floor (-1.5) -1 (rounding to zero) or -2 (rounding down) ?
I'm in the process of implementing some ieee754 floating point routines on a platform with no hardware FP and looking at various libraries and how they work while implementing my own. It seems the GNU routine in one library I have; "fix" is close to floor rounding to zero. And that's all it has - other operations have to be synthesized.
I'd really like to see an IEEE754 library for the 65C02/816 but it'll have to wait. A down-side is that it's "only" 4 bytes rather than 5, but the reality is that we rarely need more precision than what that affords. Everything more is basically peacocking in our little Basic world.... However the advantages to a 5-byte format is the ease of manipulating a 4-byte mantissa - especially if you already have good, fast routines to manipulate 32-bit quantities (in e.g. BBC Basic). IEEE format needs unpacking and re-packing for each operation unless you have the means to fuse operations such as a multiply and add where you could keep them internally in their unpacked format. Now - some "classic" minicomputer Basics do have matrix operations, but they're rare in the microcomputer world.
-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Re: A contest to reduce code size
Five byte floats are handy for being able to store four byte integers…
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: A contest to reduce code size
drogon wrote:
I'd really like to see an IEEE754 library for the 65C02/816 but it'll have to wait.
x86? We ain't got no x86. We don't NEED no stinking x86!
-
WillisBlackburn
- Posts: 50
- Joined: 14 Aug 2021
Re: A contest to reduce code size
BigEd wrote:
Five byte floats are handy for being able to store four byte integers…
Except not quite, for two reasons:
1. With a separate sign bit it's not possible represent -2,147,483,648, which you can represent with a 32-bit int. We *could* represent that if we stored the significand in two's complement form, though, which is what Woz did with his FP library. I actually did implement that originally, but it creates problems when you really need to negate a number that might be -2,147,483,648.
2. Even if you can represent -2,147,483,648, you can't easily print it, because you can really only safely print 9 digits. If you print 10 digits, and if the number is in the range -(2^31) to 2^31-1, you'll probably get the right output, but if the number is 5 billion-something, then the 10th digit will just be garbage.
Re: A contest to reduce code size
Checked CINT on TRS80 and it does truncate (same like FIX) instead of round to nearest for some reason. And also noticed that INT on VC83 truncates instead of flooring.
-
WillisBlackburn
- Posts: 50
- Joined: 14 Aug 2021
Re: A contest to reduce code size
soci wrote:
Checked CINT on TRS80 and it does truncate (same like FIX) instead of round to nearest for some reason. And also noticed that INT on VC83 truncates instead of flooring.
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: A contest to reduce code size
It's not clear to me what the difference is between INT and CINT, but it may be subtle.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!
Mike B. (about me) (learning how to github)
Mike B. (about me) (learning how to github)
Re: A contest to reduce code size
barrym95838 wrote:
It's not clear to me what the difference is between INT and CINT, but it may be subtle.
There are four rounding operations in common use: floor rounds towards negative infinity, ceil rounds towards positive infinity, truncate rounds towards zero, round rounds towards the nearest integer. Round should return the nearest even integer if the fractional part is exactly one half, but simple implementations don't always do that.
-
WillisBlackburn
- Posts: 50
- Joined: 14 Aug 2021
Re: A contest to reduce code size
Okay, you all wanted INT to do floor, so now it does floor.
Since now ROUND(X) is exactly INT(X+0.5), I removed ROUND to save 10 or so bytes.
Since now ROUND(X) is exactly INT(X+0.5), I removed ROUND to save 10 or so bytes.