Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.forth > #26622 > unrolled thread
| Started by | Brad Eckert <hwfwguy@gmail.com> |
|---|---|
| First post | 2013-10-17 16:04 -0700 |
| Last post | 2013-10-19 18:39 +0200 |
| Articles | 10 — 4 participants |
Back to article view | Back to comp.lang.forth
Short and sweet (F.) Brad Eckert <hwfwguy@gmail.com> - 2013-10-17 16:04 -0700
Re: Short and sweet (F.) Brad Eckert <hwfwguy@gmail.com> - 2013-10-18 06:12 -0700
Re: Short and sweet (F.) mhx@iae.nl - 2013-10-18 10:40 -0700
Re: Short and sweet (F.) "Ed" <invalid@invalid.com> - 2013-10-19 11:58 +1000
Re: Short and sweet (F.) Brad Eckert <hwfwguy@gmail.com> - 2013-10-20 07:12 -0700
Re: Short and sweet (F.) Brad Eckert <hwfwguy@gmail.com> - 2013-10-20 08:51 -0700
Re: Short and sweet (F.) Brad Eckert <hwfwguy@gmail.com> - 2013-10-20 09:20 -0700
Re: Short and sweet (F.) "Ed" <invalid@invalid.com> - 2013-10-24 22:34 +1000
Re: Short and sweet (F.) "Ed" <invalid@invalid.com> - 2013-10-19 11:12 +1000
Re: Short and sweet (F.) Hans Bezemer <the.beez.speaks@gmail.com> - 2013-10-19 18:39 +0200
| From | Brad Eckert <hwfwguy@gmail.com> |
|---|---|
| Date | 2013-10-17 16:04 -0700 |
| Subject | Short and sweet (F.) |
| Message-ID | <ac476f9d-1c23-49bf-aaa8-f0f32c22211f@googlegroups.com> |
CREATE FPOWERS
1E0 F, 1E1 F, 1E2 F, 1E3 F, 1E4 F, 1E5 F, 1E6 F, 1E7 F, 1E8 F, 1E9 F,
1E10 F, 1E11 F, 1E12 F, 1E13 F, 1E14 F, 1E15 F, 1E16 F, 1E17 F, 1E18 F,
: (F.) ( -- c_addr u ) ( float: r -- )
FDUP F0< FABS FDUP FLOG F>S ( minus? log10[r] ) ( float: r )
0 MAX \ for small r, trade readability for precision
<# >R PRECISION 1- R@ - ( minus? trailing ) ( R: log10[r] )
DUP 0< IF DROP \ r > 10^PRECISION
R> 18 - 0 MAX DUP >R \ assuming decimal BASE,
0 ?DO 10E0 F/ LOOP F>D \ reduce range if too big for #
ELSE \ ordinary numbers
PRECISION FLOATS FPOWERS + F@ F* F>D \ r*10^PRECISION
R> 0 ?DO # LOOP 5 0 D+ # \ round
<# ROT 0 ?DO # LOOP 0 >R \ after decimal
THEN
[CHAR] . HOLD
R> 0 ?DO [CHAR] 0 HOLD LOOP \ big num overflow
#S ROT SIGN #> \ before decimal
;
: Q ( f -- )
CR FDUP F. CR (F.) TYPE ;
\ Improvement over typical F.
\ 1. Outputs to string
\ 2. Rounding
\ 3. Freakin' small
[toc] | [next] | [standalone]
| From | Brad Eckert <hwfwguy@gmail.com> |
|---|---|
| Date | 2013-10-18 06:12 -0700 |
| Message-ID | <bd63bd4c-5947-441c-8336-118f4ca650a4@googlegroups.com> |
| In reply to | #26622 |
On Thursday, October 17, 2013 7:04:25 PM UTC-4, Brad Eckert wrote:
> CREATE FPOWERS ...
>
FLOG barfs on 0e0. Since FLOG isn't exact, I removed it. The following version of (F.) is a single 64x16 screen.
I wrote this to display floating point numbers by setting the text of dialog items in Windows. The built-in F. uses TYPE and EMIT.
\ Convert float to string 2013.10.17 BNE
CREATE FPOWERS 1E0 F, 1E1 F, 1E2 F, 1E3 F, 1E4 F, 1E5 F, 1E6 F,
1E7 F, 1E8 F, 1E9 F, 1E10 F, 1E11 F, 1E12 F, 1E13 F, 1E14 F,
1E15 F, 1E16 F, 1E17 F, 1E18 F, : [PRS] FLOATS FPOWERS + F@ ;
: F.RIGHT ( .right d -- d' ) 5 0 D+ # <# ROT 0 ?DO # LOOP ;
: (F.) ( -- c_addr u ) ( float: r -- )
<# FDUP F0< FABS 0
BEGIN FDUP DUP 1+ [PRS] F< 0= OVER 18 < AND WHILE 1+ REPEAT
>R PRECISION 1- R@ - ( -? .right | r: log10[r])
DUP 0< IF DROP \ r >= 10^PRECISION
R> 18 - 0 MAX DUP >R \ assuming decimal BASE,
0 ?DO 10E0 F/ LOOP F>D \ reduce range if too big for #
ELSE PRECISION [PRS] F* F>D \ r * 10^PRECISION
R> 0 ?DO # LOOP F.RIGHT 0 >R \ rounded, after decimal
THEN [CHAR] . HOLD R> 0 ?DO [CHAR] 0 HOLD LOOP \ 0overflow
#S ROT SIGN #> ; \ left of decimal
\ Float to string with fixed number of digits after the decimal
: (F.F) ( digits -- c_addr u ) ( float: r -- )
FDUP F0< SWAP FABS DUP 1+ [PRS] F* F>D
<# F.RIGHT [CHAR] . HOLD #S ROT SIGN #>
;
[toc] | [prev] | [next] | [standalone]
| From | mhx@iae.nl |
|---|---|
| Date | 2013-10-18 10:40 -0700 |
| Message-ID | <50a120cf-fe42-419b-9177-73d3584aa648@googlegroups.com> |
| In reply to | #26630 |
On Friday, October 18, 2013 3:12:22 PM UTC+2, Brad Eckert wrote: >> CREATE FPOWERS ... >> > FLOG barfs on 0e0. Since FLOG isn't exact, I removed it. Then there is a problem with the IEEE arithmetic implementation in your Forth or on your CPU. FORTH> 0e Q 0.000000000000000000 0.00000000000000000 ok FORTH> 0e flog +e. -INF ok FORTH> 3.141592653589793235e Q 3.141592653589793235 3.14159265358979323 ok FORTH> -3.14159265358979325569e Q -3.141592653589793256 -3.14159265358979326 ok FORTH> 1e-19 Q 0.000000000000000000 0.00000000000000000 ok FORTH> 5.6e-19 Q 0.000000000000000001 0.00000000000000000 ok FORTH> 558123456789e-19 Q 0.000000055812345679 0.00000005581234568 ok -marcel
[toc] | [prev] | [next] | [standalone]
| From | "Ed" <invalid@invalid.com> |
|---|---|
| Date | 2013-10-19 11:58 +1000 |
| Message-ID | <l3slho$it4$1@speranza.aioe.org> |
| In reply to | #26635 |
mhx@iae.nl wrote: > On Friday, October 18, 2013 3:12:22 PM UTC+2, Brad Eckert wrote: > >> CREATE FPOWERS ... > >> > > FLOG barfs on 0e0. Since FLOG isn't exact, I removed it. > > Then there is a problem with the IEEE arithmetic implementation > in your Forth or on your CPU. > > FORTH> 0e Q > 0.000000000000000000 > 0.00000000000000000 ok > > FORTH> 0e flog +e. -INF ok Log(0) is an ambiguous condition so expect anything.
[toc] | [prev] | [next] | [standalone]
| From | Brad Eckert <hwfwguy@gmail.com> |
|---|---|
| Date | 2013-10-20 07:12 -0700 |
| Message-ID | <25b4e671-a604-458f-bd6c-44766db674fd@googlegroups.com> |
| In reply to | #26635 |
On Friday, October 18, 2013 1:40:18 PM UTC-4, m...@iae.nl wrote: > > Then there is a problem with the IEEE arithmetic implementation > Actually, FLOG is fine. F>S throws a "divide by 0" error on -INF. > > FORTH> 3.141592653589793235e Q > 3.141592653589793235 > 3.14159265358979323 ok > There's a difference between how SwiftForth and your forth interpret PRECISION. I should probably use a variable instead of the system's PRECISION so (F.) can have different precision than F0= and friends.
[toc] | [prev] | [next] | [standalone]
| From | Brad Eckert <hwfwguy@gmail.com> |
|---|---|
| Date | 2013-10-20 08:51 -0700 |
| Message-ID | <eb821afd-6e40-4caf-aae4-316c5afb5cbf@googlegroups.com> |
| In reply to | #26654 |
On Sunday, October 20, 2013 10:12:59 AM UTC-4, Brad Eckert wrote: > On Friday, October 18, 2013 1:40:18 PM UTC-4, m...@iae.nl wrote: > >> FORTH> 3.141592653589793235e Q >> 3.141592653589793235 >> 3.14159265358979323 ok > > There's a difference between how SwiftForth and your forth interpret > PRECISION. > Leading zeros don't count in the "significant figures". 3 set-precision ok pi f. 3.14 ok <--- iForth may print 3.141 pi 1e1 f/ f. 0.31 ok <--- SwiftForth drops the 4 pi 1e2 f* f. 314. ok pi 1e3 f* f. 3140. ok
[toc] | [prev] | [next] | [standalone]
| From | Brad Eckert <hwfwguy@gmail.com> |
|---|---|
| Date | 2013-10-20 09:20 -0700 |
| Message-ID | <563d104d-0bcf-4bb4-8778-8d857f4348a4@googlegroups.com> |
| In reply to | #26655 |
On Sunday, October 20, 2013 11:51:31 AM UTC-4, Brad Eckert wrote:
> 3 set-precision ok
> pi f. 3.14 ok <--- iForth may print 3.141
> pi 1e1 f/ f. 0.31 ok <--- SwiftForth drops the 4
> pi 1e2 f* f. 314. ok
> pi 1e3 f* f. 3140. ok
I'll just follow SwiftForth on this. Handling the "<1 case" is an unnecessary hassle.
I made PRECISION variable in the following code, which is two blocks
plus shadow blocks. I've taken to putting shadow blocks to the
side (starting at column 68) in text files and labeling them such
that formatting programs can switch back and forth between screen,
80-column text and 132-column text files.
\ Convert float to string [1/2] 2013.10.18 BNE
CREATE FPOWERS 1E0 F, 1E1 F, 1E2 F, 1E3 F, 1E4 F, 1E5 F, 1E6 F,
1E7 F, 1E8 F, 1E9 F, 1E10 F, 1E11 F, 1E12 F, 1E13 F, 1E14 F,
1E15 F, 1E16 F, 1E17 F, 1E18 F,
VARIABLE FP.DIGITS 8 FP.DIGITS ! ( significant digits )
: FPWR[N] ( idx -- r ) FLOATS FPOWERS + F@ ;
: F.RIGHT ( .right d -- d' ) 5 0 D+ # <# ROT 0 ?DO # LOOP ;
: (F.F) ( digits -- c_addr u ) ( float: r -- )
FDUP F0< SWAP FABS DUP 1+ FPWR[N] F* F>D
<# F.RIGHT [CHAR] . HOLD #S ROT SIGN #> ;
: FENORM ( granularity -- exponent ) ( float: r1 -- r2 )
>R FDUP F0< FABS 0 ( -? exponent | r: gran )
BEGIN FDUP 1E0 F< WHILE 1E18 F* 18 - REPEAT
BEGIN FDUP 1E18 F< 0= WHILE 1E17 F/ 17 + REPEAT 18
BEGIN 2DUP + R@ MOD FDUP OVER FPWR[N] F< OR WHILE 1- REPEAT
DUP FPWR[N] F/ + SWAP R> DROP IF FNEGATE THEN ;
\ Convert float to string [1/2] 2013.10.18 BNE
\ Table of 10^n, where n ranges
\ from 0 to the number of digits in a signed double.
\ Digits of precision in FP output
\ Gets floating point 10^idx, where idx = 0 to 18.
\ Convert digits right of decimal, discards last digit to round.
\ Float to string with fixed number of digits after the decimal.
\ Assume total number of digits is less than 19.
\ Normalize float for scientific or engineering output.
\ Granularity is 3 for engineering format, 1 for scientific.
\ Increase r to 1.0 or above.
\ If very large, decrease to 1.0 or above.
\ Look up divisor, skipping to lower divisors to meet
\ granularity requirement. Avoids noise of multiple "10e0 F/".
\ Convert float to string [2/2] 2013.10.18 BNE
: (F.) ( -- c_addr u ) ( float: r -- )
<# FDUP F0< FABS FLOG 0E0 FMAX F>S >R FP.DIGITS @ 1- R@ -
DUP 0< IF DROP R> 18 - 0 MAX DUP >R
0 ?DO 10E0 F/ LOOP F>D
ELSE FP.DIGITS @ FPWR[N] F* F>D
R> 0 ?DO # LOOP F.RIGHT 0 >R
THEN [CHAR] . HOLD R> 0 ?DO [CHAR] 0 HOLD LOOP
#S ROT SIGN #> ;
: (FES) ( gran -- |f: r -- ) FENORM (F.) TYPE ." E" (.) TYPE ;
: FS. ( r -- ) 1 (FES) ; : FE. ( r -- ) 3 (FES) ;
\ Convert float to string [2/2] 2013.10.18 BNE
\ Convert float to a string using numeric output buffer.
\ Save sign, get numbers to the right of the decimal.
\ There are more digits in this number than FP.DIGITS wants.
\ Assuming decimal BASE, reduce range if too big for F>D.
\ r * 10^FP.DIGITS
\ Round up and convert the part to the right of the decimal.
\ Really big numbers have trailing zeros.
\ Convert stuff left of the decimal.
\ Simple text output of scientific numbers:
\ if you need string output, you'll need to concatenate stuff.
: Q ( r -- ) CR FDUP F. FDUP CR (F.) TYPE CR ;
4 FP.DIGITS ! 4 SET-PRECISION
: PIS ( lo hi -- ) SWAP DO PI 10e0 I S>F F** F* Q LOOP ;
-3 20 PIS
9.99999999999E0 Q
10.00000000001E0 Q
[toc] | [prev] | [next] | [standalone]
| From | "Ed" <invalid@invalid.com> |
|---|---|
| Date | 2013-10-24 22:34 +1000 |
| Message-ID | <l4b0me$dnr$1@speranza.aioe.org> |
| In reply to | #26655 |
Brad Eckert wrote: > ... > > 3 set-precision ok > pi f. 3.14 ok <--- iForth may print 3.141 > pi 1e1 f/ f. 0.31 ok <--- SwiftForth drops the 4 iForth interpreted PRECISION to mean 'decimal places' > Leading zeros don't count in the "significant figures". Clearly they do in the SwiftForth universe :)
[toc] | [prev] | [next] | [standalone]
| From | "Ed" <invalid@invalid.com> |
|---|---|
| Date | 2013-10-19 11:12 +1000 |
| Message-ID | <l3sise$e5m$1@speranza.aioe.org> |
| In reply to | #26622 |
Brad Eckert wrote:
> ...
> \ Improvement over typical F.
> \ 1. Outputs to string
> \ 2. Rounding
> \ 3. Freakin' small
Compare with 'fracout' posted a year ago ...
1. Output to string
2. Rounding
3. Smaller (165 bytes vs. 248 for short&sweet)
4. No dependency on mantissa fitting a double number
fracout:
-1e 3e f/ 15 (f.) cr type
-0.333333333333333
short&sweet:
-1e 3e f/ (f.) cr type
-0.00000214748365
5. No dependency on separate f.p stack
6. Optional comma'd output
Fracout is king, long live fracout!
[toc] | [prev] | [next] | [standalone]
| From | Hans Bezemer <the.beez.speaks@gmail.com> |
|---|---|
| Date | 2013-10-19 18:39 +0200 |
| Message-ID | <5262b4e8$0$15961$e4fe514c@news2.news.xs4all.nl> |
| In reply to | #26638 |
Ed wrote: > Fracout is king, long live fracout! Agreed! Added to the 4tH library - easy (much easier than.. you know..) port! Thx!! Hans Bezemer
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.forth
csiph-web