Author Topic: Scientific or exponential notation remover  (Read 324 times)

bplus

• Forum Resident
• Posts: 5300
• B+ Knot again!
Scientific or exponential notation remover
« on: September 04, 2020, 07:51:14 PM »
I am testing last function in Steve's Math Evaluator and ran into a curiosity for n = 1 in default Single.

The 0's jump 1 extra 0 between 7 and 8, all other numbers I've tested seem OK

Code: QB64: [Select]
1. _TITLE "N2S\$ testing for a scientific notation remover" 'b+ 2020-09-04
2.
3. ' looks pretty good except for one little bug
4.
5. IF 1 THEN ' < 0 to skip section, 1 to run section
6.     n = 1 ' has an odd bug jump -7 to -8 moves right 1 extra 0
7.     FOR i = 0 TO 20
8.         PRINT i, N2S\$(STR\$(n * 10 ^ -i));
9.         LOCATE CSRLIN, 54: PRINT N2S\$(STR\$(n * 10 ^ i))
10.
11. IF 0 THEN '  < 0 to skip section, 1 to run section
12.     n## = 1 ' but this OK too
13.     'n## = 27.0123456789 'OK
14.     'n## = (1 / 3) 'OK
15.     FOR i = 0 TO 20
16.         PRINT i, N2S\$(STR\$(n## * 10 ^ -i));
17.         LOCATE CSRLIN, 54: PRINT N2S\$(STR\$(n## * 10 ^ i))
18.
19. FUNCTION N2S\$ (EXP\$) 'remove scientific Notation to String (~40 LOC)
20.     'SMcNeill Jan 7, 2020 ref: https://www.qb64.org/forum/index.php?topic=1555.msg112989#msg112989
21.     'Last Function in code marked Best Answer (removed debug comments and blank lines added these 2 lines.)
22.     t\$ = LTRIM\$(RTRIM\$(EXP\$))
23.     IF LEFT\$(t\$, 1) = "-" OR LEFT\$(t\$, 1) = "N" THEN sign\$ = "-": t\$ = MID\$(t\$, 2)
24.     dp = INSTR(t\$, "D+"): dm = INSTR(t\$, "D-")
25.     ep = INSTR(t\$, "E+"): em = INSTR(t\$, "E-")
26.     check1 = SGN(dp) + SGN(dm) + SGN(ep) + SGN(em)
27.     IF check1 < 1 OR check1 > 1 THEN N2S = EXP\$: EXIT SUB 'If no scientic notation is found, or if we find more than 1 type, it's not SN!
28.     SELECT CASE l 'l now tells us where the SN starts at.
29.         CASE IS < dp: l = dp
30.         CASE IS < dm: l = dm
31.         CASE IS < ep: l = ep
32.         CASE IS < em: l = em
33.     l\$ = LEFT\$(t\$, l - 1) 'The left of the SN
34.     r\$ = MID\$(t\$, l + 1): r&& = VAL(r\$) 'The right of the SN, turned into a workable long
35.     IF INSTR(l\$, ".") THEN 'Location of the decimal, if any
36.         IF r&& > 0 THEN
37.             r&& = r&& - LEN(l\$) + 2
38.             r&& = r&& + 1
39.         l\$ = LEFT\$(l\$, 1) + MID\$(l\$, 3)
40.     SELECT CASE r&&
41.         CASE 0 'what the heck? We solved it already?
42.             'l\$ = l\$
43.         CASE IS < 0
44.             FOR i = 1 TO -r&&
45.                 l\$ = "0" + l\$
46.             l\$ = "0." + l\$
47.             FOR i = 1 TO r&&
48.                 l\$ = l\$ + "0"
49.             l\$ = l\$
50.     N2S\$ = sign\$ + l\$
51.
52.
53.

@SMcNeill  a puzzle for you.

I don't think this will stop me from using it, as is, though getting this curiosity explained or fixed would be nice :)

« Last Edit: September 04, 2020, 07:52:51 PM by bplus »

SMcNeill

• QB64 Developer
• Forum Resident
• Posts: 2782
Re: Scientific or exponential notation remover
« Reply #1 on: September 04, 2020, 08:01:25 PM »
I’ll dig into it in a few days.  Today and Tomorrow, I’m down watching over my mom (she’s dealing with early onset Alzheimer's), so it’ll probably be Sunday by the earliest, before I can sort out what’s going on.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

SMcNeill

• QB64 Developer
• Forum Resident
• Posts: 2782
Re: Scientific or exponential notation remover
« Reply #2 on: September 06, 2020, 04:31:52 PM »
Good catch!  Negative notation isn't something which we see very often, and the glitch here is mine, instead of QB64s.

1e-8 -- this says we have 1, then shift it to the right 8 places, giving us 0.00000001...

Unfortunately, I simply interpeted it as "add 8 zeros in front", giving us 0.000000001...  This is an extra 0, which we don't actually have!

(In my defense, 1e8 is as simple as "add 8 zeros behind", giving us 100000000...  Unfortunately, the same logic doesn't quite hold true, in this case, for negative exponents.)

The change is extremely simple to implement:

Down on line 52, change the following:             FOR i = 1 TO -r&&

To:              FOR i = 1 TO (-r&& - 1)

That's it!  One little alteration and it works as it should.  This glitch is entirely from my own flawed logic with notations, and has nothing at all to do with QB64.

1e-1 = 0.1, not .01, as I was thinking it did.

Fixed code is below, for those who simply don't want to alter it themselves:

Code: QB64: [Select]
1. _TITLE "N2S\$ testing for a scientific notation remover" 'b+ 2020-09-04
2.
3. ' looks pretty good except for one little bug
4.
5. IF 1 THEN ' < 0 to skip section, 1 to run section
6.     n = 1 ' has an odd bug jump -7 to -8 moves right 1 extra 0
7.     FOR i = 0 TO 20
8.         PRINT i, N2S\$(STR\$(n * 10 ^ -i));
9.         LOCATE CSRLIN, 50: PRINT N2S\$(STR\$(n * 10 ^ i))
10.
11. IF 0 THEN '  < 0 to skip section, 1 to run section
12.     n## = 1 ' but this OK too
13.     'n## = 27.0123456789 'OK
14.     'n## = (1 / 3) 'OK
15.     FOR i = 0 TO 20
16.         PRINT i, N2S\$(STR\$(n## * 10 ^ -i));
17.         LOCATE CSRLIN, 54: PRINT N2S\$(STR\$(n## * 10 ^ i))
18.
19. FUNCTION N2S\$ (EXP\$) 'remove scientific Notation to String (~40 LOC)
20.     'SMcNeill Jan 7, 2020 ref: https://www.qb64.org/forum/index.php?topic=1555.msg112989#msg112989
21.     'Last Function in code marked Best Answer (removed debug comments and blank lines added these 2 lines.)
22.     t\$ = LTRIM\$(RTRIM\$(EXP\$))
23.     IF LEFT\$(t\$, 1) = "-" OR LEFT\$(t\$, 1) = "N" THEN sign\$ = "-": t\$ = MID\$(t\$, 2)
24.     dp = INSTR(t\$, "D+"): dm = INSTR(t\$, "D-")
25.     ep = INSTR(t\$, "E+"): em = INSTR(t\$, "E-")
26.     check1 = SGN(dp) + SGN(dm) + SGN(ep) + SGN(em)
27.     IF check1 < 1 OR check1 > 1 THEN N2S = EXP\$: EXIT SUB 'If no scientic notation is found, or if we find more than 1 type, it's not SN!
28.     SELECT CASE l 'l now tells us where the SN starts at.
29.         CASE IS < dp: l = dp
30.         CASE IS < dm: l = dm
31.         CASE IS < ep: l = ep
32.         CASE IS < em: l = em
33.     l\$ = LEFT\$(t\$, l - 1) 'The left of the SN
34.     r\$ = MID\$(t\$, l + 1): r&& = VAL(r\$) 'The right of the SN, turned into a workable long
35.     IF INSTR(l\$, ".") THEN 'Location of the decimal, if any
36.         IF r&& > 0 THEN
37.             r&& = r&& - LEN(l\$) + 2
38.             r&& = r&& + 1
39.         l\$ = LEFT\$(l\$, 1) + MID\$(l\$, 3)
40.     SELECT CASE r&&
41.         CASE 0 'what the heck? We solved it already?
42.             'l\$ = l\$
43.         CASE IS < 0
44.             FOR i = 1 TO (-r&& - 1)
45.                 l\$ = "0" + l\$
46.             l\$ = "0." + l\$
47.             FOR i = 1 TO r&&
48.                 l\$ = l\$ + "0"
49.             l\$ = l\$
50.     IF sign\$ = "" THEN sign\$ = " "
51.     N2S\$ = sign\$ + l\$
52.
« Last Edit: September 06, 2020, 04:34:05 PM by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

SMcNeill

• QB64 Developer
• Forum Resident
• Posts: 2782
Re: Scientific or exponential notation remover
« Reply #3 on: September 06, 2020, 04:37:11 PM »
And a version which does a little better keeping formatting looking the same with our results:

Code: QB64: [Select]
1. _TITLE "N2S\$ testing for a scientific notation remover" 'b+ 2020-09-04
2.
3. ' looks pretty good except for one little bug
4.
5. IF 1 THEN ' < 0 to skip section, 1 to run section
6.     n = 1 ' has an odd bug jump -7 to -8 moves right 1 extra 0
7.     FOR i = 0 TO 20
8.         PRINT i, N2S\$(STR\$(n * 10 ^ -i));
9.         LOCATE CSRLIN, 50: PRINT N2S\$(STR\$(n * 10 ^ i))
10.
11. IF 0 THEN '  < 0 to skip section, 1 to run section
12.     n## = 1 ' but this OK too
13.     'n## = 27.0123456789 'OK
14.     'n## = (1 / 3) 'OK
15.     FOR i = 0 TO 20
16.         PRINT i, N2S\$(STR\$(n## * 10 ^ -i));
17.         LOCATE CSRLIN, 54: PRINT N2S\$(STR\$(n## * 10 ^ i))
18.
19. FUNCTION N2S\$ (EXP\$) 'remove scientific Notation to String (~40 LOC)
20.     'SMcNeill Jan 7, 2020 ref: https://www.qb64.org/forum/index.php?topic=1555.msg112989#msg112989
21.     'Last Function in code marked Best Answer (removed debug comments and blank lines added these 2 lines.)
22.     t\$ = LTRIM\$(RTRIM\$(EXP\$))
23.     IF LEFT\$(t\$, 1) = "-" OR LEFT\$(t\$, 1) = "N" THEN sign\$ = "-": t\$ = MID\$(t\$, 2)
24.     dp = INSTR(t\$, "D+"): dm = INSTR(t\$, "D-")
25.     ep = INSTR(t\$, "E+"): em = INSTR(t\$, "E-")
26.     check1 = SGN(dp) + SGN(dm) + SGN(ep) + SGN(em)
27.     IF check1 < 1 OR check1 > 1 THEN N2S = EXP\$: EXIT SUB 'If no scientic notation is found, or if we find more than 1 type, it's not SN!
28.     SELECT CASE l 'l now tells us where the SN starts at.
29.         CASE IS < dp: l = dp
30.         CASE IS < dm: l = dm
31.         CASE IS < ep: l = ep
32.         CASE IS < em: l = em
33.     l\$ = LEFT\$(t\$, l - 1) 'The left of the SN
34.     r\$ = MID\$(t\$, l + 1): r&& = VAL(r\$) 'The right of the SN, turned into a workable long
35.     IF INSTR(l\$, ".") THEN 'Location of the decimal, if any
36.         IF r&& > 0 THEN
37.             r&& = r&& - LEN(l\$) + 2
38.             r&& = r&& + 1
39.         l\$ = LEFT\$(l\$, 1) + MID\$(l\$, 3)
40.     SELECT CASE r&&
41.         CASE 0 'what the heck? We solved it already?
42.             'l\$ = l\$
43.         CASE IS < 0
44.             FOR i = 1 TO (-r&& - 1)
45.                 l\$ = "0" + l\$
46.             l\$ = "." + l\$
47.             FOR i = 1 TO r&&
48.                 l\$ = l\$ + "0"
49.             l\$ = l\$
50.     IF sign\$ = "" THEN sign\$ = " "
51.     N2S\$ = sign\$ + l\$
52.

https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

bplus

• Forum Resident
• Posts: 5300
• B+ Knot again!
Re: Scientific or exponential notation remover
« Reply #4 on: September 06, 2020, 06:29:06 PM »
Thanks @SMcNeill

I suspected it had something to do with switching from no notation to notation with the number string coming in.

Funny, you added a space if sign was positive whereas I had trimmed space off before sending the number string back if it didn't have notation in it. :)

bplus

• Forum Resident
• Posts: 5300
• B+ Knot again!
Re: Scientific or exponential notation remover
« Reply #5 on: September 06, 2020, 07:08:23 PM »
@SMcNeill  OK now big problem with floats as input: they are all off by 1 zero in decimals when N2S\$ is not just trimming the input string. Before it was just the integer 1 that failed as input but other non float inputs seemed OK.

I have * all outputs when N2S\$ only trims the input string
Code: QB64: [Select]
1. _TITLE "N2S\$ testing for a scientific notation remover" 'b+ 2020-09-04
2. ' looks pretty good except for one little bug
3. ' 2020-09-06 fixed ? see comment line with this date
4.
5.
6. IF 0 THEN ' < 0 to skip section, 1 to run section    2020-09-06 this section looks good!
7.     n = 1 ' has an odd bug jump -7 to -8 moves right 1 extra 0     OK beautiful 2020-09-06!
8.     'n = 0.003 ' 2020-09-06 this looks fine too
9.     'n = 1000 / 3 '2020-09-06 fine!
10.     FOR i = 0 TO 20
11.         PRINT i, N2S\$(STR\$(n * 10 ^ -i));
12.         LOCATE CSRLIN, 54: PRINT N2S\$(STR\$(n * 10 ^ i))
13.
14. IF 1 THEN '  < 0 to skip section, 1 to run section
15.     n## = 1.0 ' but this OK too (when n=1 wasn't working)   2020-09-06 Now this is wrong!!!
16.     n## = 1000 / 3 'OK                                      and this
17.     n## = .003 'OK                                          and this
18.     FOR i = 0 TO 20
19.         'PRINT i, STR\$(n## * 10 ^ -i), N2S\$(STR\$(n## * 10 ^ -i))
20.         PRINT i, N2S\$(STR\$(n## * 10 ^ -i));
21.         LOCATE CSRLIN, 54: PRINT N2S\$(STR\$(n## * 10 ^ i))
22.
23. FUNCTION N2S\$ (EXP\$) 'remove scientific Notation to String (~43 LOC)
24.     DIM t\$, sign\$, L\$, R\$, r&&
25.     DIM dp AS INTEGER, dm AS INTEGER, ep AS INTEGER, em AS INTEGER, check1 AS INTEGER, L AS INTEGER, i AS INTEGER
26.     'SMcNeill Jan 7, 2020 ref: https://www.qb64.org/forum/index.php?topic=1555.msg112989#msg112989
27.     'Last Function in code marked Best Answer (removed debug comments and blank lines added these 2 lines.)
28.     t\$ = _TRIM\$(EXP\$)
29.     IF LEFT\$(t\$, 1) = "-" OR LEFT\$(t\$, 1) = "N" THEN sign\$ = "-": t\$ = MID\$(t\$, 2)
30.     dp = INSTR(t\$, "D+"): dm = INSTR(t\$, "D-")
31.     ep = INSTR(t\$, "E+"): em = INSTR(t\$, "E-")
32.     check1 = SGN(dp) + SGN(dm) + SGN(ep) + SGN(em)
33.     IF check1 < 1 OR check1 > 1 THEN N2S\$ = _TRIM\$(EXP\$) + "*": EXIT SUB 'If no scientic notation is found, or if we find more than 1 type, it's not SN!
34.     SELECT CASE L 'l now tells us where the SN starts at.
35.         CASE IS < dp: L = dp
36.         CASE IS < dm: L = dm
37.         CASE IS < ep: L = ep
38.         CASE IS < em: L = em
39.     L\$ = LEFT\$(t\$, L - 1) 'The left of the SN
40.     R\$ = MID\$(t\$, L + 1): r&& = VAL(R\$) 'The right of the SN, turned into a workable long
41.     IF INSTR(L\$, ".") THEN 'Location of the decimal, if any
42.         IF r&& > 0 THEN
43.             r&& = r&& - LEN(L\$) + 2
44.             r&& = r&& + 1
45.         L\$ = LEFT\$(L\$, 1) + MID\$(L\$, 3)
46.     SELECT CASE r&&
47.         CASE 0 'what the heck? We solved it already?
48.             'l\$ = l\$
49.         CASE IS < 0
50.             FOR i = 1 TO (-r&& - 1) 'fix SMcNeill 2020-09-06
51.                 L\$ = "0" + L\$
52.             L\$ = "." + L\$ ' 2020-09-06 removed 0 of "0." + L\$  to keep consistent with other returns
53.             FOR i = 1 TO r&&
54.                 L\$ = L\$ + "0"
55.             L\$ = L\$
56.     N2S\$ = sign\$ + L\$
57.
58.

It seems if you get the floats correct the integers (or just 1 is off). Fix 1 and all the floats are off.

bplus

• Forum Resident
• Posts: 5300
• B+ Knot again!
Re: Scientific or exponential notation remover
« Reply #6 on: September 08, 2020, 04:38:29 PM »
Sorry @SMcNeill

You had it right the first time!

I finally tracked down the source of the bug. It was in the test, we needed to DIM i as INTEGER for the powers of 10.

Here is the proof:
Code: QB64: [Select]
1. _TITLE "N2S\$ testing for a scientific notation remover" 'b+ 2020-09-04
2. ' source of bug tracked down 2020-09-08
3. ' looks pretty good except for one little bug fixed now
4.
5. 'It was because i was not dim'd as an integer!!!
6. DIM i AS INTEGER '<<<<<<<<<<<<<<<<<<<< Oh man!!!!  this was the problem!!! Discovered 2020-09-08
7.
8. IF 0 THEN ' < 0 to skip section, 1 to run section
9.     DIM n AS INTEGER '<<<<<<<<<<< comment out to test single
10.     n = 1 ' has an odd bug jump -7 to -8 moves right 1 extra 0   fixed!!
11.     FOR i = 0 TO 20
12.         PRINT i,
13.         LOCATE CSRLIN, 5: PRINT N2S\$(STR\$(n * 10 ^ -i));
14.         LOCATE CSRLIN, 54: PRINT N2S\$(STR\$(n * 10 ^ i))
15.     n## = 1 ' but this OK too
16.     'n## = 27.0123456789 'OK
17.     'n## = (1 / 3) 'OK
18.     FOR i = 0 TO 20
19.         PRINT i;
20.         LOCATE CSRLIN, 5: PRINT N2S\$(STR\$(n## * 10 ^ -i));
21.         LOCATE CSRLIN, 54: PRINT N2S\$(STR\$(n## * 10 ^ i))
22.
23. FUNCTION N2S\$ (EXP\$) 'remove scientific Notation to String (~40 LOC)
24.     'SMcNeill Jan 7, 2020 ref: https://www.qb64.org/forum/index.php?topic=1555.msg112989#msg112989
25.     'Last Function in code marked Best Answer (removed debug comments and blank lines added these 2 lines.)
26.     t\$ = LTRIM\$(RTRIM\$(EXP\$))
27.     IF LEFT\$(t\$, 1) = "-" OR LEFT\$(t\$, 1) = "N" THEN sign\$ = "-": t\$ = MID\$(t\$, 2)
28.     dp = INSTR(t\$, "D+"): dm = INSTR(t\$, "D-")
29.     ep = INSTR(t\$, "E+"): em = INSTR(t\$, "E-")
30.     check1 = SGN(dp) + SGN(dm) + SGN(ep) + SGN(em)
31.     IF check1 < 1 OR check1 > 1 THEN N2S = _TRIM\$(EXP\$): EXIT SUB 'If no scientic notation is found, or if we find more than 1 type, it's not SN!
32.     SELECT CASE l 'l now tells us where the SN starts at.
33.         CASE IS < dp: l = dp
34.         CASE IS < dm: l = dm
35.         CASE IS < ep: l = ep
36.         CASE IS < em: l = em
37.     l\$ = LEFT\$(t\$, l - 1) 'The left of the SN
38.     r\$ = MID\$(t\$, l + 1): r&& = VAL(r\$) 'The right of the SN, turned into a workable long
39.     IF INSTR(l\$, ".") THEN 'Location of the decimal, if any
40.         IF r&& > 0 THEN
41.             r&& = r&& - LEN(l\$) + 2
42.             r&& = r&& + 1
43.         l\$ = LEFT\$(l\$, 1) + MID\$(l\$, 3)
44.     SELECT CASE r&&
45.         CASE 0 'what the heck? We solved it already?
46.             'l\$ = l\$
47.         CASE IS < 0
48.             FOR i = 1 TO -r&&
49.                 l\$ = "0" + l\$
50.             l\$ = "." + l\$
51.             FOR i = 1 TO r&&
52.                 l\$ = l\$ + "0"
53.             l\$ = l\$
54.     N2S\$ = sign\$ + l\$
55.

PS Changes: I am trimming the EXP\$ when no exponent is found and I am using .xxxx not 0.xxxx
Among other reasons it makes this test very consistent in output between exponent mods and no exponent mods.
« Last Edit: September 08, 2020, 04:47:03 PM by bplus »

MWheatley

• Newbie
• Posts: 57
Re: Scientific or exponential notation remover
« Reply #7 on: September 09, 2020, 06:00:08 PM »
Hi.

Where's the original post on this?  Happy to download the code and do some testing.

Malcolm

bplus

• Forum Resident
• Posts: 5300
• B+ Knot again!
Re: Scientific or exponential notation remover
« Reply #8 on: September 09, 2020, 07:01:17 PM »
Hi.

Where's the original post on this?  Happy to download the code and do some testing.

Malcolm

It's listed right with the N2S\$ function.

MWheatley

• Newbie
• Posts: 57
Re: Scientific or exponential notation remover
« Reply #9 on: September 15, 2020, 04:10:10 PM »
I'm sorry: "it's listed right" doesn't mean anything to me.  Where?

Malcolm

bplus

• Forum Resident
• Posts: 5300
• B+ Knot again!
Re: Scientific or exponential notation remover
« Reply #10 on: September 15, 2020, 04:16:31 PM »
I'm sorry: "it's listed right" doesn't mean anything to me.  Where?

Malcolm

"its listed right with the N2S\$ function."

What you don't like my demo of the N2S\$ Function? ;(

OK here it is highlighted from that function, so you can see it better.

FUNCTION N2S\$ (EXP\$) 'remove scientific Notation to String (~40 LOC)
'SMcNeill Jan 7, 2020 ref: https://www.qb64.org/forum/index.php?topic=1555.msg112989#msg112989
'Last Function in code marked Best Answer (removed debug comments and blank lines added these 2 lines.)

« Last Edit: September 15, 2020, 04:23:57 PM by bplus »