r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[!REBOL3-OLD1]

Pekr
9-Nov-2009
[19472]
yes, I think that bounties of type - pick your bounty - would not 
work here.
Rebolek
9-Nov-2009
[19473]
If we don't try, we won't know
Pekr
9-Nov-2009
[19474x2]
e.g. networking protocols - those could be done imo only by Gabriele, 
or BrianH ... (hope I don't offend others). Carl might be picky, 
what code gets in. It definitely can't be done by me for example 
:-)
I like http://bounties.morphzone.org/, because you can see, who 
contributed. The trouble might be - does any such system allows cancellation 
ob bounty, their merge, etc? What happens to money, if bounty's goal 
is not fulfilled?
Henrik
9-Nov-2009
[19476]
that's an odd money distribution. the most important thing is site 
maintenance? :-)
Geomol
9-Nov-2009
[19477x4]
I looked a bit more on MOD, MODULO, REMAINDER and //. Isn't there 
too many of those functions? I found, MOD is giving some strange 
results:

>> mod -8. -3.
== -5.0
It makes sense to me to either just use the C ways of doing modulus, 
if it's fast:

% for integer! and
fmod () for decimal!


or do it in a more correct way mathematically, maybe (pseudocode):

result of a // b = a - floor (a, b) * b
See: http://en.wikipedia.org/wiki/Modular_arithmetic#Functional_representation_of_the_remainder
and: http://functions.wolfram.com/IntegerFunctions/Mod/02/
I searched the scripts in the library at rebol.org, and only a handful 
(which is very few) use MOD. A script or two even make their own 
version of MOD to give correct output.
Henrik
9-Nov-2009
[19481]
AFAIK MOD and // are not the same.
Geomol
9-Nov-2009
[19482x2]
I think, you are right. It seems, REMAINDER should do the same as 
//. My question is, if we need 3 different modulus functions? Today 
we have REMAINDER, MOD and MODULO, and at least MOD is giving some 
strange results in some cases. I would guess, having one function 
and one operator should be enough.
Ask yourself, if you were going to use a modulus function, which 
one would you use? And why?
Henrik
9-Nov-2009
[19484]
I suppose it depends on the situation. I guess there would be three 
different versions, because Carl saw a need for them all. I discovered 
the difference when I used MOD in a situation where // worked as 
it should.
PeterWood
9-Nov-2009
[19485]
I tried mod 3.3 1.1 - it reutrns a negtative number - I have reported 
this in CureCode
Geomol
9-Nov-2009
[19486]
There are related bugs, it seems. This should return a value close 
to zero:

>> 3.3 - ((round/floor 3.3 / 1.1) * 1.1)
== 1.1


It's not good, that there still are bugs on such a basic level. (Often 
when I dig into these things, I say to myself, that I should shut 
up and wait for a release.)
BrianH
9-Nov-2009
[19487x2]
Right now, all op! functions redirect to corresponding action! functions. 
// redirects to REMAINDER, which is why we need it.
When you run into major errors like PeterWood's above, report them. 
Since MOD and MODULO are mezzanine, they can be fixed right away 
by someone with the right math knowledge. Ladislav?
Geomol
9-Nov-2009
[19489x2]
I'm not questioning, that we need a modulus function (REMAINDER). 
I'm questioning, if we really need 3 of them. If REMAINDER doesn't 
do, what it's supposed to, then I would fix that instead of adding 
2 new functions.
Brian, no they can't be fixed right away. See my example with round/floor 
above. That's the way to calculate a modulus, and it doesn't work. 
:)
BrianH
9-Nov-2009
[19491x3]
From what I can tell from the code though, modulus and remainder 
aren't exactly the same concepts. But, I don't have that math knowledge. 
The mezzanines claim to do extra error checking, but I don't know 
what part of their code does that.
If there is an error, and the math within the functions makes sense, 
then there is an error in the underlying operators somewhere that 
needs to be tracked down. Ladislav? :)
From your code, it looks like this is the problem:
>> round/floor 3.3 / 1.1
== 2.0
>> 3.3 / 1.1
== 3.0


1.1 and 3.3 aren't exactly representable in IEEE754 encoding, so 
the 3.0 value you see is actually a little less than 3.0.
Rebolek
9-Nov-2009
[19494]
Brian, when I try round/floor 3.3 / 1.1 it returns 1.1 (2.100.94.3.1 
on XP)
BrianH
9-Nov-2009
[19495]
If you want exact decimal math, you have to switch to a different 
underlying representation, such as that used by money!:
>> round/floor $3.3 / $1.1
== $3
>> $3.3 / $1.1
== $3.0000000000000000000000000
Geomol
9-Nov-2009
[19496]
I think, I see, what happening now. If 3.3 / 1.1 is just below 3.0, 
then the round/floor will return 2.0, which is ok. So my example 
might not be a real problem after all, unless it give different results 
on different platforms.
BrianH
9-Nov-2009
[19497]
Bolek, are you sure you put in /, instead of //? Cause that sounds 
extra weird, since I am also testing on XP.
Rebolek
9-Nov-2009
[19498]
Ah, my stupid fault  :)
>> round/floor 3.3 1.1
== 1.1
:)
Geomol
9-Nov-2009
[19499]
Hm, the round/floor way probably shouldn't be used, when dealing 
with decimals. It should then just use the C function, fmod ().
BrianH
9-Nov-2009
[19500x3]
Geomol, that inaccuracy is built into the standard, and floating 
point hardware tends to follow that standard. It's a side effect 
of the fact that IEEE754 floating point numbers are internally base 
2, and in base 2 the decimal value 0.1 is an infinite number just 
like 1/3 is in base 10.
And if you look at the source of MOD and MODULUS, neither of them 
uses round/floor :)
Sorry, MODULO, not MODULUS :)
Geomol
9-Nov-2009
[19503x3]
Brian, I know about IEEE754! :)
I wrote much of the documentation about it.
I just tested, the C function, fmod (3.3, 1.1), also returns 1.1. 
:)
BrianH
9-Nov-2009
[19506x2]
I figured so, since if I knew about it it must be pretty basic :)
I think that the difference between // and MOD is in how they handle 
negative numbers. Modulus (as a math concept, as I recall) isn't 
defined for negative numbers at all. Programming languages tend to 
punt when it comes to this, so // works the most common way, and 
MOD converts it to the next most common way.
Geomol
9-Nov-2009
[19508]
The reason is understandable too. When the two decimals tested can 
be divided without remainder (the remainder comes close to zero), 
we can't use the result. It's because the division can be on either 
side of zero, so the rounding will give zero or -1.0.
BrianH
9-Nov-2009
[19509x3]
>> $3.3 // $1.1
== $0
The $ in this case just being a sigil for a different numeric representation 
that works better in this kind of situation.
(Good work on that, Ladislav!)
Geomol
9-Nov-2009
[19512x2]
I also tested, that it takes equal amount of cpu time to do this 
in C, where a and b are of type double:

fmod (a, b)

or

a - floor (a / b) * b

Same can be said for integers, where we would use % in C.
I conclude, it makes sense to drop MOD and MODULO, and then use the 
calculation using floor for both integers and decimals. It will give 
the mathematically best result, and it will perform as good as using 
% and fmod in C.
BrianH
9-Nov-2009
[19514x3]
MOD and MODULO are supposed to be different from // for *negative* 
numbers.
If you look at the source for those functions, you will see that 
MOD calls // internally, and MODULO calls MOD.
Neither call floor (unless // calls it internally).
Geomol
9-Nov-2009
[19517]
And if you look in HELP MODULO, it looks like a hack to fix some 
problem:


Wrapper for MOD that handles errors like REMAINDER. Negligible values 
(compared to A and B) are rounded to zero.
BrianH
9-Nov-2009
[19518x3]
Yup. Which is where my math knowledge left off. I can see the math 
they use, but not why it is necessary.
I get MOD, I think: It's that negative values thing. MODULO seems 
to deal with the epsilon, afaict.
Ladislav wrote them, iirc. If he thinks they're necessary I'll take 
his word for it :)
Geomol
9-Nov-2009
[19521]
Ops, I said something wrong, when saying, the division can be on 
either side of zero. The division is of course close to a whole number, 
but can be on either side of that number, so the rounding can be 
that number (if the result lie above) or one below that number (if 
the result is below). Using ROUND instead of ROUND/FLOOR solves it.