You are not logged in. You can browse in the PowerBASIC Community, but you must click Login (top right) before you can post. If this is your first visit, check out the FAQ or Sign Up.
John has not come back with how many disagreements he is having, if any.
> I wonder if it might be a test-code problem.
When collaborating at distance early testing would benefit from not using random data. I haven't seen the above example repeated and who knows when it will turn up again. Using non-random data and we'd all see it.
>
...
Unfortunately, on my machine the ASMRoundUp is not behaving in the same way with John's last code as it is with a stand alone written when Paul Dixon posted it. If it did the number of disagreements would plummet aiding a better concentration on them. John has not come back with how many disagreements he is having, if any.
I'll see what happens on my computer if I get a chance tonight.
>John has not come back with how many disagreements he is having, if any.
Six minutes, is that service or what? Actually, I'd been testing trying to duplicate your results for like an hour, wrote the post, previewed it, and your post appeared just then hehheh.
...
When collaborating at distance early testing would benefit from not using random data. I haven't seen the above example repeated and who knows when it will turn up again. Using non-random data and we'd all see it.
Using random data should not result in a lack of repeatability. If the same compiler is used (e.g., PBCC 4.04) and the RANDOMIZE statement is not used, the results will be repeatable by anyone using the same program. Unfortunately, John's program reseeds his random number generator in a way that is similar to the RANDOMIZE statement.
I first asked how many disagreements you were having in post #216 - a little more than six minutes ago.
> comment out the lines
Will do.
> Using random data should not result in a lack of repeatability.
Period is ~2^61 (2*10^18) EXT values 'before repeating--many years.
That is ~2^29 * RND's repeatability. We should be using RND, IMO. Once everything is 'ironed out' with that then a ~2^61 should be used, our machines given a mammoth task and the fishing rods brought down from the loft.
> Using random data should not result in a lack of repeatability.
Period is ~2^61 (2*10^18) EXT values 'before repeating--many years.
That is ~2^29 * RND's repeatability. We should be using RND, IMO. Once everything is 'ironed out' with that then a ~2^61 should be used, our machines given a mammoth task and the fishing rods brought down from the loft.
I'm afraid that you've misinterpreted the term, repeatability. I stated above that, "if the same compiler is used (e.g., PBCC 4.04) and the RANDOMIZE statement is not used, the results will be repeatable by anyone using the same program." This concept of repeatabiliy does not have anything to do with the number of random values that are generated before a pseudo-random number will repeat durng the run of a program.
> and the RANDOMIZE statement is not used, the results will be repeatable by anyone using the same program.
Agreed, although I'd have used 'repeated' rather than 'repeatable', and also true when RANDOMIZE is used with a fixed seed allowing a different entry to the sequence than that of the default seed.
However, I questioned "Using random data should not result in a lack of repeatability."
It should result in no repeatability, although I'd prefer repetition, else the data would not be random. The data may have been generated randomly but if that same data is repeated on each 'run' then we have effectively a random number table being read from the same starting point.
Question: What do you get when two pedants meet up? A request for sandwiches and another pot of tea.
Last edited by David Roberts; 8 Jul 2008, 12:27 AM.
Reason: Preference for repetition.
...
However, I questioned "Using random data should not result in a lack of repeatability."
It should result in no repeatability, although I'd prefer repetition, else the data would not be random. The data may have been generated randomly but if that same data is repeated on each 'run' then we have effectively a random number table being read from the same starting point.
Oh, if only English weren't your second language! Here's the statement in context:
Using random data should not result in a lack of repeatability. If the same compiler is used (e.g., PBCC 4.04) and the RANDOMIZE statement is not used, the results will be repeatable by anyone using the same program. Unfortunately, John's program reseeds his random number generator in a way that is similar to the RANDOMIZE statement.
I think it is quite apparent that I was referring to pseudo-random numbers since, obviously, these are the only type of "random" numbers that PB generates. It should be just as apparent, to anyone not wearing blinders, that the term "repeatability" refers to the ability of different testers to obtain the same results when running the program. If this concept eludes you this time, David, it will have to remain that way.
This all came about because you stated in a previous post:
"When collaborating at distance early testing would benefit from not using random data. I haven't seen the above example repeated and who knows when it will turn up again. Using non-random data and we'd all see it."
Being such an expert on random numbers, why didn't you realize that John's program was not generating true random data? Oh! But, of course, you did. Then why is it alright for you to use the term "random data" loosely, but not me?
i feel i am ready to move on after testing my rounding routine, roundme4
maybe the roundme4 function should be name "roundtoboot" because i add a 1 four digits more to the right of rounding factor.
as far as i can tell, it does a good job and proves most effective when rounding to 12 or less decimal places
if paul dixon's code is not the most current for rounding up on a 5 digit then please pm it to me so i can change this code
i also increase some figures in the number summited to the rounding routines for from johns test to test more digits to the right of the decimal point.
Code:
'compiled with pbcc 4.04
'round.bas
#COMPILE EXE
#DIM ALL
GLOBAL xdiffs AS QUAD
FUNCTION round_dixon(BYVAL number AS EXT, BYVAL number_rounding_digits AS LONG) AS EXT
LOCAL temp AS QUAD
temp = 10^number_rounding_digits
FUNCTION = SGN(number)*INT(ABS(number*temp) + 0.5##)/temp
END FUNCTION
FUNCTION roundme4(BYREF X AS EXT, BYREF Factor AS LONG) AS EXT
LOCAL isgn AS LONG
LOCAL xx AS EXT
LOCAL MM AS EXT
LOCAL stemp AS STRING
xx=ABS(x)
IF xx < (99999999999999999##/1&) THEN
isgn=SGN(X)
mm=1&/(10^(factor+3&))
FUNCTION=isgn*ROUND((mm+xx),factor)
EXIT FUNCTION
END IF
FUNCTION=ROUND(x,factor)
END FUNCTION
FUNCTION PBMAIN () AS LONG
LOCAL M,x,y,z AS EXT
LOCAL roundto,count,numdig AS LONG
'goto johnstest
'loop number 1 this loop was created for Walter's testing
count=0
FOR m=0## TO 10000## STEP 1&/1000&
roundto=0
GOSUB dotheroundtest
roundto=1
GOSUB dotheroundtest
roundto=2
GOSUB dotheroundtest
roundto=3
GOSUB dotheroundtest
roundto=4
GOSUB dotheroundtest
roundto=5
GOSUB dotheroundtest
roundto=6
GOSUB dotheroundtest
roundto=7
GOSUB dotheroundtest
roundto=8
GOSUB dotheroundtest
roundto=9
GOSUB dotheroundtest
roundto=10
GOSUB dotheroundtest
roundto=11
GOSUB dotheroundtest
roundto=12
GOSUB dotheroundtest
roundto=13
GOSUB dotheroundtest
roundto=14
GOSUB dotheroundtest
'WAITKEY$
INCR count
IF count MOD 500000 = 0 THEN
PRINT "just showing count and value"+STR$(count),m
PRINT "xdiffs = " & STR$(xdiffs)
PRINT "% of diff to tries= " & STR$(xdiffs/count)
END IF
NEXT m
PRINT "done with loop 1 Walter's testing"
'WAITKEY$
johnstest:
'loop number 2 this loop was created for John's testing but roundup is not tested only roundme1 and roundme2
count=0
DO
roundto = RND(0,10)
numDig = 2
INCR count
M= ROUND(RND * 10^numDig, roundto+1)
roundto=roundto+8
m=m/1000000&
GOSUB dotheroundtest
IF count MOD 500000 = 0 THEN
PRINT "just showing count"+STR$(count)
PRINT "xdiffs = " & STR$(xdiffs)
END IF
LOOP
dotheroundtest:
y=round_dixon(M,roundto)
z=roundMe4(M,roundto)
y=VAL(STR$(y,18))
z=VAL(STR$(z,18))
IF y<>z THEN
INCR xdiffs
IF (y-z)<(-1&/10000000000000&) THEN RETURN
' IF TRIM$(STR$(y-z))="-.001" THEN RETURN
' IF TRIM$(STR$(y-z))="-.01" THEN RETURN
' IF TRIM$(STR$(y-z))="-.1" THEN RETURN
' IF TRIM$(STR$(y-z))="-1" THEN RETURN
' return
CLS
PRINT "------------------------------------------------------------------"
PRINT "round to decimal places = ",roundto
PRINT "Original value as a number = ",M
PRINT "Original value as a string = " + STR$(M,18)
PRINT "round_dixon as a number =", STR$(y,18)
PRINT "roundme4 as a number =", STR$(z,18)
PRINT "differences between y and z = ",y-z
PRINT "Total tries = " & STR$(count)
PRINT "# of differences = " & STR$(xdiffs)
PRINT "% of diff to tries= " & STR$(xdiffs/count)
WAITKEY$
'sleep 10
END IF
RETURN
END FUNCTION
> If this concept eludes you this time, David, it will have to remain that way.
If it eluded me, Walter, then I would probably not have written "Agreed, although I'd have used 'repeated' rather than 'repeatable', and also true when RANDOMIZE is used with a fixed seed allowing a different entry to the sequence than that of the default seed."
> why didn't you realize that John's program was not generating true random data? Oh! But, of course, you did. Then why is it alright for you to use the term "random data" loosely, but not me?
The generation of true random data as opposed to pseudo random data is irrelevant in this context. In fact, it is irrelevant most of the time provided that the prng has a half decent period and why most folk drop the pseudo, including statisticians.
I think that the reason we are not seeing 'eye to eye', Walter, is that if the same sequence of random data, pseudo random data if you like, is used then, for me, that sequence then becomes non-random data. Blindly sticking a pin into a random number table provides us with random data. If I tell you where the pin landed and you used that as your starting point as well then I'd call that using non-random data. We are still using shuffled decks as opposed to ordered ones but the shuffled decks are duplicated.
For me then the status of random, pseudo random, data exists in two forms. An analogy for me is Schrödinger's wave equation: Open your eyes and it collapses.
Added:
> Oh, if only English weren't your second language!
> It should be just as apparent, to anyone not wearing blinders
> Being such an expert on random numbers
Do you have to go there, Walter? Smilies say a lot. Not using smilies also says a lot.
I think that the reason we are not seeing 'eye to eye', Walter, is that if the same sequence of random data, pseudo random data if you like, is used then, for me, that sequence then becomes non-random data...
From my perspective, the reason that we are not seeing "eye to eye" is that I resent your picking apart and redefining words that I use in order to support your position.
I continued to participate in this thread even though I felt it was was going in the wrong direction (read visual rounding). I have learned a lot by doing so, and I hope that, in a small way, I have added to the discussion. And, up to now, it has been fun. However, since my comments are now being attacked by the most picayune sniping, even though those comments were intended as helpful suggestions, I will move on.
No, I haven't. I do if I use 0.5 in double format as opposed to single format but I got the data anomaly before I 'fiddled' with Paul's code. Perhaps I did one 'run' too many after another fiddle. It happens, doesn't it. It does with me anyway.
Perhaps the time has come, the walrus said, to get the fishing rods out of the loft and let the machine rip for sometime.
As for the last 5 syndrome they are so few and far between as to be liveable with, I guess.
From my perspective, the reason that we are not seeing "eye to eye" is that I resent your picking apart and redefining words that I use in order to support your position.
I don't do it to support my position. I would do it to support your position. I am pedantic and qualify as a PITA much of the time. Diplomacy is not my best suit either being a classic Joe Blunt. Having said that I do not rub everyone up the wrong way. There are some here who leave me standing and you have exchanged words with them as I have.
I have learned a lot by doing so, and I hope that, in a small way, I have added to the discussion. And, up to now, it has been fun. However, since my comments are now being attacked by the most picayune sniping, even though those comments were intended as helpful suggestions, I will move on.
Walter, without further ado, I apologise. You have put more into this thread than I have.
This code, incrementing by 5, I think highlights what most users IMHO would consider a problem in the ASMRoundUp code, because it occurs--rarely but consistently--in commonly seen numbers, not just 15 decimals out. Yes, no, maybe?
Code:
'compiled with pbcc 4.04
'roundUpV2g.bas
#COMPILE EXE
#DIM ALL
#REGISTER NONE
FUNCTION ASMRoundUp(num AS EXT, digits AS LONG) AS EXT
'################################################################
'# This is an ASM version of:
'# temp = 10^number_rounding_digits
'# FUNCTION = SGN(number)*INT(ABS(number*temp) + 0.5##)/temp
'#
'# note: Parameters are passed by reference as it's faster.
'# if this is changed then the code must be altered to match
'################################################################
LOCAL OldControlWord AS INTEGER
!jmp skip 'jump over the following lookup tables
table:
'this is just a lookup table of all the powers of 10 from 0 to 18
!dd &h1,0 '1
!dd &hA,0 '10
!dd &h64,0 '100
!dd &h3E8,0 '1000
!dd &h2710,0 '10000
!dd &h186A0,0 '100000
!dd &hF4240,0 '1000000
!dd &h989680,0 '10000000
!dd &h5F5E100,0 '100000000
!dd &h3B9ACA00,0 '1000000000
!dd &h540BE400,&h2 '10000000000
!dd &h4876E800,&h17 '100000000000
!dd &hD4A51000,&hE8 '1000000000000
!dd &h4E72A000,&h918 '10000000000000
!dd &h107A4000,&h5AF3 '100000000000000
!dd &hA4C68000,&h38D7E '1000000000000000
!dd &h6FC10000,&h2386F2 '10000000000000000
!dd &h5D8A0000,&h1634578 '100000000000000000
!dd &hA7640000,&hDE0B6B3 '1000000000000000000
!dd &h89E80000,&h8AC72304 '10000000000000000000
!dd &h63100000,&h6BC75E2D '100000000000000000000
half:
!dd &h3f000000 'the number 0.5 in single format
FPControlWordRoundToZeroEXT:
!dw &h01F3F 'control word to set FPU to round toward zero with extended precision
skip:
!mov eax,digits 'look up the scale required for this many digits
!mov eax,[eax] 'must do this as digits is a function parameter so I get the address, not the value
!fild qword ptr table[eax*8] 'get the scale factor
!mov eax,num## 'again, got the address of num## as it's a function parameter
!fld tbyte ptr [eax] 'load num##
!fmul st(0),st(1) 'num## * temp
!fld dword ptr half 'get the number 0.5
!mov ecx,79
!bt [eax],ecx 'check the sign of num##
!jnc skp
!fchs 'if num -ve then make 0.5 -ve too
skp:
!faddp st(1),st(0) 'num## * temp + 0.5
!fstcw OldControlWord 'save original control word
!fldcw FPControlWordRoundToZeroEXT 'change FPU control word to round toward zero
!frndint 'round to nearest integer -> INT(num## * temp + 0.5)
!fldcw OldControlWord 'restore original control word
!fdivrp st(1),st(0) 'INT(num## * temp + 0.5) / temp
!fstp function 'save answer
END FUNCTION
FUNCTION roundUpV3(a AS EXT, b AS LONG) AS EXT
'---------------------------------------------------------------------------------------
'rounds "a" to "b" digits past decimal point, but up on 5 instead of using
'banker's rounding. It rounds as you would expect by just looking at the decimal numbers,
'as if the computer were a decimal computer. eg. roundUpV3(123.4545, 3) becomes 123.455.
'---------------------------------------------------------------------------------------
STATIC x AS EXT
STATIC qa AS QUAD
STATIC fillOnce, sizeA AS LONG
DIM ten(18) AS STATIC QUAD
IF a < 0 THEN 'handle negatives
x = ROUND(a, b) 'in 8.04 (and probably most recent CC ver.) round to even, or banker's rounding
IF x <= a THEN 'rounded up, so no need to go thru hoops.
FUNCTION = x
EXIT FUNCTION
END IF
ELSE
x = ROUND(a, b) 'in 8.04 (and probably most recent CC ver.) round to even, or banker's rounding
IF x >= a THEN 'rounded up
FUNCTION = x
EXIT FUNCTION
END IF
END IF
'make powers of 10 to avoid exponent calcs
IF fillOnce = 0 THEN
ten(00) = 1
ten(01) = 10
ten(02) = 100
ten(03) = 1000
ten(04) = 10000
ten(05) = 100000
ten(06) = 1000000
ten(07) = 10000000
ten(08) = 100000000
ten(09) = 1000000000
ten(10) = 10000000000
ten(11) = 100000000000
ten(12) = 1000000000000
ten(13) = 10000000000000
ten(14) = 100000000000000
ten(15) = 1000000000000000
ten(16) = 10000000000000000
ten(17) = 100000000000000000
ten(18) = 1000000000000000000
fillOnce = 1
END IF
'how big is a?
SELECT CASE ABS(a)
CASE < ten(00): sizeA = 01: qa = a * ten(18)
CASE < ten(01): sizeA = 02: qa = a * ten(17)
CASE < ten(02): sizeA = 03: qa = a * ten(16)
CASE < ten(03): sizeA = 04: qa = a * ten(15)
CASE < ten(04): sizeA = 05: qa = a * ten(14)
CASE < ten(05): sizeA = 06: qa = a * ten(13)
CASE < ten(06): sizeA = 07: qa = a * ten(12)
CASE < ten(07): sizeA = 08: qa = a * ten(11)
CASE < ten(08): sizeA = 09: qa = a * ten(10)
CASE < ten(09): sizeA = 10: qa = a * ten(09)
CASE < ten(10): sizeA = 11: qa = a * ten(08)
CASE < ten(11): sizeA = 12: qa = a * ten(07)
CASE < ten(12): sizeA = 13: qa = a * ten(06)
CASE < ten(13): sizeA = 14: qa = a * ten(05)
CASE < ten(14): sizeA = 15: qa = a * ten(04)
CASE < ten(15): sizeA = 16: qa = a * ten(03)
CASE < ten(16): sizeA = 17: qa = a * ten(02)
CASE < ten(17): sizeA = 18: qa = a * ten(01)
CASE ELSE
FUNCTION = a
EXIT FUNCTION 'exit because a is too big to round
END SELECT
IF sizeA + b > 18 THEN
FUNCTION = a
EXIT FUNCTION 'exit because round digits too big
END IF
qa = qa \ ten(18 - (sizeA + b)) 'make whole EXT effectively an integer
sizeA = qa MOD 10
IF sizeA = 5 THEN 'is last digit a 5?
FUNCTION = ((qa + 10) \ 10) / ten(b)'if so round up prev. digits and replace decimal point in correct position
ELSEIF sizeA = -5 THEN 'or -5
FUNCTION = ((qa - 10) \ 10) / ten(b)'if so round up prev. digits and replace decimal point in correct position
ELSE
FUNCTION = x
END IF
END FUNCTION
FUNCTION PBMAIN () AS LONG
'---------------------------------------------------------------------------------------
'this stops at differences between asmRoundUp and roundUpV3 rounding by a 5 increment.
'---------------------------------------------------------------------------------------
LOCAL M AS EXT
LOCAL roundto, ii AS LONG
' OPEN "c:\RoundV3asmDiff.txt" FOR APPEND AS #1
? "rounding..."
roundTo = 3 'round to 3 digits
FOR ii = 5 TO 2100000 STEP 5'000
m = ii / 100000
IF roundUpV3(m, roundTo) <> asmRoundUp(m, roundTo) THEN
? "asm" & STR$(m, 18), STR$(asmRoundUp(m, roundTo), 18) & STR$(roundTo)
? "rV3" & " ", STR$(roundUpV3(m, roundTo), 18) & STR$(ii) & " sequential"
WAITKEY$
END IF
NEXT
? "done"
WAITKEY$
END FUNCTION
is there any program listed yet that will round correctly to certain many decimals using the 5 up rule.
i had mentioned in cbasic, the program i had programmed in before, it had a 14 digit accuracy.
from the manual, and i do believe the language has been turned over to the public, you can see where it states reals(EXTENDED) variables are rounded.
the rounding as far as i can tell is using the 5 up rule.
i believe it was rounding the 15,16,17 and/or 18 digit to 14 for accuracy purposes.
i am ok with an accuracy of out to 14 decimals for rounding purposes on the 5 up rule.
can we get there and guarantee to 14 decimals on a 5 up rule.
here is a paragraph from the manual defining number variables
in another manual for cbasic, it states that numbers are kept in the IEEE standard format.
Two types of numeric quantities are supported by CBASIC: real and integer. A real constant is written in either fixed format or exponential notation. In both cases, it contains from one to fourteen digits, a sign, and a decimal point. In exponential notation, the exponent is of the form Esdd, where s, if present, is a valid sign, +, -, or blank, and where dd is one or two valid digits. The sign is the exponent sign and should not be confused with the optional sign of the mantissa. The numbers range from 1.0E-64 to 9.9999999999999E62. Although only fourteen significant digits are maintained internally by CBASIC, more digits can be included in a real constant. Real constants are rounded to fourteen significant digits.
i might of just hit the sweet spot.
i am ok with a 14 digit rounding on the 5 up rule right
this might work on rounding up to 14 digits and it also seems promising on the 15 and 16 digit round as well
i have tried to stay clear of using the VAL statement, but if it works i have to use it
place the statement after the results of my roundme4 routine
Code:
z=VAL(STR$(z)) ' do not use z=VAL(STR$(z,16))
this seems to have a negating effect of my adding a 1 four digits to the right of rounding decimal where i was getting returned values that ended with .~~~~000001
an example would be rounding to 14 digits the value of 52.515 with a returning value of 52.51500000000001 before the above code add in, where now i appear to be getting a returned value of 52.515
added:
actually in the above test i posted several post prior
you can change the code from
z=VAL(STR$(z,18)) to z=VAL(STR$(z))
We process personal data about users of our site, through the use of cookies and other technologies, to deliver our services, and to analyze site activity. For additional details, refer to our Privacy Policy.
By clicking "I AGREE" below, you agree to our Privacy Policy and our personal data processing and cookie practices as described therein. You also acknowledge that this forum may be hosted outside your country and you consent to the collection, storage, and processing of your data in the country where this forum is hosted.
Comment