Comment On Fun with Maths

Ward is not a lucky man. When the two main (read: only) developers of a flash application were fired, he was called in to clean up their mess. As he puts it, A couple of months ago, I was asked to do a small update (5 hours work) to an application made by those 2 people (they made it together, so its even worse!). This application is for a government agency, and they already paid in advance for updates. I was told just to replace the database with updated material, compile an installer and ship it. [expand full text]
« PrevPage 1 | Page 2Next »

Re: [CodeSOD] Fun with Maths

2007-01-03 10:04 • by Whiskey Tango Foxtrot? Over.
Rewrite from scratch? Sometimes I *wish* I could do that here...

Re: [CodeSOD] Fun with Maths

2007-01-03 10:19 • by Saladin

I want to find whoever wrote those bits and slap them around.

Even though they've been seen before, those sorts of mistakes are indicative of a lack of even the most fundamental knowledge.  Not knowing to use < 0 to determine if something is negative?  You don't even need to have touched a computer before to realize that a negative number will always be less than zero.  And don't get me started on the abuse of the modulo operator...

I deeply pity whoever hired this genius, but at the same time feel that they're getting what they deserve by obviously not screening out candidates like this.  The submitter, though, certainly does not deserve being subjected to this...

Re: [CodeSOD] Fun with Maths

2007-01-03 10:26 • by patrickriva

value+=step ..... what if value at the beginning is not divisible by step?

maybe this is safer:     value = (value / step + 1) * step;

Re: [CodeSOD] Fun with Maths

2007-01-03 10:35 • by diaphanein
109411 in reply to 109410
patrickriva:

value+=step ..... what if value at the beginning is not divisible by step?

maybe this is safer:     value = (value / step + 1) * step;

Only if you assume integer division.

Re: [CodeSOD] Fun with Maths

2007-01-03 10:40 • by LE
109412 in reply to 109410
You are laughing at perfectly (unless step is BIG - which slows down the function) working function and replace it with buggy ones. Who should be laughed at?

Re: [CodeSOD] Fun with Maths

2007-01-03 10:43 • by aikii
This convert-to-string-and-look-for-minus-sign seems to be a classic. Throughout all lines of code on earth that test for negative, how many times it happens ? 0.1% ?

There is a easy way if you don't like negatives. Just compute exp(x). If exp(x) is between 0 and 1, x is negative.

Or multiply x by itself, then test if x and the result have different signs.

captcha : perfection. Yup, why making it simple when you can make it perfect ? Easy path to WTFisms.

Re: [CodeSOD] Fun with Maths

2007-01-03 10:46 • by patrickriva
109417 in reply to 109411
Anonymous:
patrickriva:

value+=step ..... what if value at the beginning is not divisible by step?

maybe this is safer:     value = (value / step + 1) * step;

Only if you assume integer division.

 You're right, anyway being the syntax C/C#/Java-ish it was
for me natural to think at integer division as well as to think
value and step to be integers variables.

Re: [CodeSOD] Fun with Maths

2007-01-03 10:52 • by some moron
flash offers such a rich and deep seam in the dirty coal-mine of WTFs that I'd always assumed it was too base to post any of the turd I deal with on a near daily basis. it provides a near perfect environment to nurture the most unintelligible, mangled and generally screwed up code. A surprisingly large proportion of flash programmers never went anywhere near a computing related education, and are mostly self taught "pros" whose attempts at anything beyond trivial toy applications will end up costing their employers very dearly indeed! beware. With that in mind, if you are any good at it, the pickings can be quite tasty, especially with the up and up of online advertising.

Re: [CodeSOD] Fun with Maths

2007-01-03 10:56 • by G-Unit
109420 in reply to 109416
While you those tricks will work to determine the sign of a number, I'd image that if(x<0) uses the least amount of clock cycles.

Re: [CodeSOD] Fun with Maths

2007-01-03 10:56 • by Eric
109421 in reply to 109410

isn't more something like:

value = value + value%step + 1 ?

Re: [CodeSOD] Fun with Maths

2007-01-03 11:04 • by Gerard
109424 in reply to 109421
Anonymous:

isn't more something like:

value = value + value%step + 1 ?

 
No:

value = value - value%step + step
 

Re: [CodeSOD] Fun with Maths

2007-01-03 11:20 • by allo
109432 in reply to 109424
Anonymous:
Anonymous:

isn't more something like:

value = value + value%step + 1 ?

 
No:

value = value - value%step + step
 


easier:
value=value+value%step

value%step is the distance to the next number divisable by step ...

Re: [CodeSOD] Fun with Maths

2007-01-03 11:29 • by Oliver
109437 in reply to 109424

[snipped many replacement solutions for the first "divisibility" snippet]

So what's wrong with the solution the original author used? I see only the problem that the comment seems a but misleading (isn't "value" always divisible by "value"?). Apart from that, the original snippet apparently works as expected and requires virtually no thinking about - you can't really say the same about the other proposed solutions... Actually I'm using such heavily non-elegant solutions often if there's the danger that the elegant solution would also be error-prone and difficult to understand for others.

Btw. who designed this strange forum posting usability where I have to decide whether I want to quote a previous posting _before_ getting an editor window? How about adding a "paste as quotation" button next to the formatting buttons (and maybe removing the unncessary HTML formatting buttons instead...) ? Just my 2 cents...

Re: [CodeSOD] Fun with Maths

2007-01-03 11:32 • by Welbog
109440 in reply to 109432

No, that's not equivalent. Take an example with value = 7 and step = 5, you want to find x s.t. x > value and 5|x and x is minimal.

So x = value - (value % step) + step = 7 - 2 + 5 = 10

Whereas x = value + (value % step) = 7 + 2 = 9, which isn't what you want.

Re: [CodeSOD] Fun with Maths

2007-01-03 11:33 • by pete
109441 in reply to 109432

next_value_divisible_through_step_without_remainder = value + ((step - value) % step)

obviously modulo is difficult for some people...
 


Re: [CodeSOD] Fun with Maths

2007-01-03 11:38 • by another moron
109442 in reply to 109432
Anonymous:
Anonymous:
Anonymous:

isn't more something like:

value = value + value%step + 1 ?

 
No:

value = value - value%step + step
 


easier:
value=value+value%step

value%step is the distance to the next number divisable by step ...

 

Hahahaha. I love this forum! 

Re: [CodeSOD] Fun with Maths

2007-01-03 14:48 • by seer
109449 in reply to 109441
Anonymous:

next_value_divisible_through_step_without_remainder = value + ((step - value) % step)

obviously modulo is difficult for some people...
 

If value=7 and step=5, what is the value of (-2 % 5) ???

You might want to rethink that one...

Re: [CodeSOD] Fun with Maths

2007-01-03 14:52 • by AuMatar
109452 in reply to 109442

The real wtf is noone can get it right

 

If you want to round down to the nearest value that's a multiple of step:

 

down_value=value-value%step;

 

If you want to round up to the next value

 

up_value=value+step-value%step;

 

 

Its a really bad sign that its taken this many posts to get it right. 

Re: [CodeSOD] Fun with Maths

2007-01-03 15:10 • by anonymous
109462 in reply to 109442
During my interview for a job, the guy gave me a quiz on modular arithmetic - basically write a formula that produces each of the following input-output tables. I got it all right (though it took me way too long to think about it), but he told me that a lot of people messed up, or wrote a lot of stuff down and crossed it out. I think I probably would have as well, as I'm pretty bad at that kind of stuff, but I'd been reading a number theory book at the time.

On a related note, it would be nice if you could reliably take the modulus of negative numbers in a mathematically nice way while programming. This is possible in some programming languages but annoying in others.

Re: [CodeSOD] Fun with Maths

2007-01-03 15:19 • by Jeff
109465 in reply to 109452

It's worse than that, because if the example is in Java or C# or any other language which copied the deranged '%' behavior from C, then *all* of the replacements, including yours, break for negative numbers. (% isn't really modulus, it's remainder-after-integer-division-that-rounds-toward-zero.)

So a fixed version is:

down_value = value - ((value % step + step) % step)

up_value = value - ((value % step + step) % step) + step

 

Re: [CodeSOD] Fun with Maths

2007-01-03 15:23 • by Anonymous Coward
109468 in reply to 109440
Anonymous:

No, that's not equivalent. Take an example with value = 7 and step = 5, you want to find x s.t. x > value and 5|x and x is minimal.

So x = value - (value % step) + step = 7 - 2 + 5 = 10

Whereas x = value + (value % step) = 7 + 2 = 9, which isn't what you want.

 

But which is actually the intended behavior? Was the original code correct to begin with, or is this a bug? It's bizarre enough that we can't easily determine their intent.

In any case, the original code is WTFy enough that it should never escape without a comment explaining its intent. WTF was he TRYING to do, anyway?!
 

Re: [CodeSOD] Fun with Maths

2007-01-03 15:25 • by Marcos
109472 in reply to 109411
I'm curious about that real % operator you're talking about...

Re: [CodeSOD] Fun with Maths

2007-01-03 15:28 • by Matt
109476 in reply to 109442

Once and for all:

value += step - value%step

jeez.

Re: [CodeSOD] Fun with Maths

2007-01-03 15:37 • by submitter
109480 in reply to 109468
Anonymous:
Anonymous:

No, that's not
equivalent. Take an example with value = 7 and step = 5, you want to
find x s.t. x > value and 5|x and x is minimal.

So x = value - (value % step) + step = 7 - 2 + 5 = 10

Whereas x = value + (value % step) = 7 + 2 = 9, which isn't what you want.

 

But
which is actually the intended behavior? Was the original code correct
to begin with, or is this a bug? It's bizarre enough that we can't
easily determine their intent.

In any case, the original code
is WTFy enough that it should never escape without a comment explaining
its intent. WTF was he TRYING to do, anyway?!
 

I'm
the submitter of this one... What the original author tried to do, was
simply find out the next number that could be devided by "step". He
wrote a function for this called "calculateDistance", which had this
code in it. (makes no sense at all), and yes, "step" was BIG (so it was
looping a lot).  This application was one big wtf, rewriting it
from scratch was really worth the effort.

Re: [CodeSOD] Fun with Maths

2007-01-03 15:37 • by Zylon
109481 in reply to 109476

Obviously, the enterprisey solution would be to store the next "step" for all possible "values" in a giant SQL table.

Re: [CodeSOD] Fun with Maths

2007-01-03 15:40 • by GeneWitch

I've put way too much thought into this... Modulo operater gives you a remainder. I'm plugging arbitrary values into step and value in my head... since you guys said seven and five as values, step*value=35, and 35 is the first number you get to that fits the description. I would assume (just because i am too lazy to test it) that you wouldn't have a situation where step > value (value = 2, step = 100). correct me if i am wrong, but isn't the answer always going to be (or mostly always going to be) step*value?

Or am i misreading the "code"?

//find the next "value" divisible by "step" ?

Isn't this just a "lowest common denominator" in disguise (or whatever its inverse is)?
if step is always smaller than value....

Re: [CodeSOD] Fun with Maths

2007-01-03 15:44 • by GeneWitch
109486 in reply to 109480

Anonymous:

I'm the submitter of this one... What the original author tried to do, was simply find out the next number that could be devided by "step". He wrote a function for this called "calculateDistance", which had this code in it. (makes no sense at all), and yes, "step" was BIG (so it was looping a lot).  This application was one big wtf, rewriting it from scratch was really worth the effort.

um... ok.. if step was constant... step += step. if step was NOT constant, then you STILL don't need to loop, you just need to store what it originally was, i.e. step_constant = 5, step = 15; step+step_constant is the next number that matches.

regardless, even if step is not constant, step+=step is going to be the next number, isn't it? Or is it just waaaaay too late for me?

Re: [CodeSOD] Fun with Maths

2007-01-03 15:49 • by submitter
109487 in reply to 109486
GeneWitch:

Anonymous:

I'm the
submitter of this one... What the original author tried to do, was
simply find out the next number that could be devided by "step". He
wrote a function for this called "calculateDistance", which had this
code in it. (makes no sense at all), and yes, "step" was BIG (so it was
looping a lot).  This application was one big wtf, rewriting it
from scratch was really worth the effort.

um... ok..
if step was constant... step += step. if step was NOT constant, then
you STILL don't need to loop, you just need to store what it originally
was, i.e. step_constant = 5, step = 15; step+step_constant is the next
number that matches.

regardless, even if step is not constant,
step+=step is going to be the next number, isn't it? Or is it just
waaaaay too late for me?

 

Euhmz... i guess its late for you :)

What he was trying to do was this. Let's say he had  23 as the
value. And he wanted to know what the next number was  that could
be devided by 500.

What strikes me the most is this guy know how
to convert a Number to String, even how to take the first character
from that string... but still doesn't realize he can just check if its
smaller then 0?  

Re: [CodeSOD] Fun with Maths

2007-01-03 15:55 • by scriptkiddie
109492 in reply to 109472

Anonymous:
I'm curious about that real % operator you're talking about...

 

I believe that using the "on crack" C style % operator, true modulus would be calculated as follows:

((m+(v%m))%m)

 


... and prepares himself for the inevitable stoning... 

Come on people, is this a programmers' forum or what?

2007-01-03 16:02 • by Mike
109493 in reply to 109452

> The real wtf is noone can get it right
> If you want to round up to the next value
> up_value=value+step-value%step

Hah! You didn't get it either. Rounding up 4 on 4-grain will give you 8 with this equation. You have to account for the values that are already aligned. Hence:

/// \brief Rounds \p n up to be divisible by \p grain
template <typename T>
inline T Align (T n, size_t grain)
{
    T r = n % grain;
    T a = n + (grain - r);
    return (r ? a : n);
}

The a temporary should be used (instead of just folding the code into the conditional) because it allows the compiler to use a cmov and compile the whole thing with no jumps.

Re: [CodeSOD] Fun with Maths

2007-01-03 16:07 • by GeneWitch
109496 in reply to 109487
Anonymous:
GeneWitch:

Anonymous:

I'm the submitter of this one... What the original author tried to do, was simply find out the next number that could be devided by "step". He wrote a function for this called "calculateDistance", which had this code in it. (makes no sense at all), and yes, "step" was BIG (so it was looping a lot).  This application was one big wtf, rewriting it from scratch was really worth the effort.

um... ok.. if step was constant... step += step. if step was NOT constant, then you STILL don't need to loop, you just need to store what it originally was, i.e. step_constant = 5, step = 15; step+step_constant is the next number that matches.

regardless, even if step is not constant, step+=step is going to be the next number, isn't it? Or is it just waaaaay too late for me?

 

Euhmz... i guess its late for you :)
What he was trying to do was this. Let's say he had  23 as the value. And he wanted to know what the next number was  that could be devided by 500.

What strikes me the most is this guy know how to convert a Number to String, even how to take the first character from that string... but still doesn't realize he can just check if its smaller then 0?  

Value = 23, step = 500. increasing value 1 at a time until it was divisible by 500 = 977 iterations of that loop, giving you 1000.... how was i wrong?

Like i said in my first post, step HAS to be smaller than value otherwise it's Step+=step.
if it is smaller, then value+=step and THEN loop it. (because you're not going to find anything smaller than step+step ANYHOW... 2 is the smallest integer you can divide by and get a different result - barring 1 and 0, of course.)

Re: Come on people, is this a programmers' forum or what?

2007-01-03 16:08 • by stykom
109497 in reply to 109493
it's supposed to give 8, hence the initial increment in the original code.

Re: [CodeSOD] Fun with Maths

2007-01-03 16:11 • by stykom
109498 in reply to 109496

Value = 23, step = 500. increasing value 1 at a time until it was
divisible by 500 = 977 iterations of that loop, giving you 1000.... how
was i wrong?

you're wrong because the correct next value is 500.
 

Re: [CodeSOD] Fun with Maths

2007-01-03 16:25 • by GeneWitch
109503 in reply to 109498
Anonymous:

Value = 23, step = 500. increasing value 1 at a time until it was divisible by 500 = 977 iterations of that loop, giving you 1000.... how was i wrong?

you're wrong because the correct next value is 500.
 

if that were the case why wouldn't the code be "VALUE = STEP"?

For that matter, why even bother having a section of code? whenever you needed to know what the next divisible number was (with step being LARGER THAN VALUE) why not just use "step" in the code instead of even needing a stupid "value" variable?

Re: [CodeSOD] Fun with Maths

2007-01-03 16:27 • by jedediah

This forum rules.

Sadly, all of the above posts are WTFs.

Here's the flash solution:

 value += to_int( (((step - value % step ) - step ) + ((step - value % step ) + step) ) / 2).to_string());
 

sheesh... 

 

ps. there is no integer division in flash, at least not in the context of the original post

captcha: flash application?  

Re: [CodeSOD] Fun with Maths

2007-01-03 16:40 • by Jheriko
109508 in reply to 109505

Either this is all some kind of joke, or you mostly fail at solving trivial problems.

 
To get the to the next value divisble by step you only need to add the difference in the modulus from step

value += step - (value%step);

 
There are probably faster and nicer ways. This is just the trivial solution.

Some of you mentioned this already and others ignored it... which is even more of a WTF. How hard is reading a thread before posting your crap? 

Re: [CodeSOD] Fun with Maths

2007-01-03 16:55 • by destined

Heh...  is it me, or wasn't the purpose of the value and step code just to increment value by the step, as the original author suggested?  That is, the value is already divisible by step when it starts.  But, like other people stated, the intent is a bit confusing.

 

Re: [CodeSOD] Fun with Maths

2007-01-03 16:55 • by submitter
109514 in reply to 109503
GeneWitch:
Anonymous:

Value = 23, step
= 500. increasing value 1 at a time until it was divisible by 500 = 977
iterations of that loop, giving you 1000.... how was i wrong?

you're wrong because the correct next value is 500.
 

if that were the case why wouldn't the code be "VALUE = STEP"?

For
that matter, why even bother having a section of code? whenever you
needed to know what the next divisible number was (with step being
LARGER THAN VALUE) why not just use "step" in the code instead of even
needing a stupid "value" variable?

 

Euh... becuase if value is 1023, and step is 500, the outcome should be 1500.

And you aresaying 500 can't be devided by 500? It's probably time togo to sleep :)

Re: [CodeSOD] Fun with Maths

2007-01-03 16:57 • by GeneWitch
109515 in reply to 109508
Jheriko:

Either this is all some kind of joke, or you mostly fail at solving trivial problems.


To get the to the next value divisble by step you only need to add the difference in the modulus from step

value += step - (value%step);


There are probably faster and nicer ways. This is just the trivial solution.

Some of you mentioned this already and other ignored it... which is even more of a WTF. How hard is reading a thread before posting your crap? 

So if i come up to you, and i say, hey, jherico... the number 25000! what's the next value that is divisible by 25000 - You'd pull out a modulo operator? the variable "value" in the code snippet above is being INCREMENTED BY ONE. In ALL cases where Step is larger than value, the answer is either value=step OR value=step*2 (depending on wtf they were using it for).

Otherwise (assuming what everyone up until this point has understood, that you want to find the next VALUE divisible by step)

if (step>value)

     value=step //or for whatever reason value = step * 2 

elseif (value%step = 0) then

     value +=step

else

value = value + (step - (value%step)) //as jherico said

endif

Re: [CodeSOD] Fun with Maths

2007-01-03 16:59 • by GeneWitch
109517 in reply to 109514
Anonymous:
GeneWitch:
Anonymous:

Value = 23, step = 500. increasing value 1 at a time until it was divisible by 500 = 977 iterations of that loop, giving you 1000.... how was i wrong?

you're wrong because the correct next value is 500.
 

if that were the case why wouldn't the code be "VALUE = STEP"?

For that matter, why even bother having a section of code? whenever you needed to know what the next divisible number was (with step being LARGER THAN VALUE) why not just use "step" in the code instead of even needing a stupid "value" variable?

 

Euh... becuase if value is 1023, and step is 500, the outcome should be 1500.
And you aresaying 500 can't be devided by 500? It's probably time togo to sleep :)

I've said this at least four times now.... IF step is LARGER than value, the answer is either step, or multiples of step. If not, THEN you have to do other voodoo magic. see above post. I'm out of here, since this has been beaten to death and i hate having to repeat myself when the stuff is in the thread in black and white.

Re: [CodeSOD] Fun with Maths

2007-01-03 17:02 • by someone
109519 in reply to 109515

value is 23

increase value by 1

while value mod 500 is not equal to 0 --> increase value by 1

 

Now read this slowly. 

Re: [CodeSOD] Fun with Maths

2007-01-03 17:07 • by submitter
109521 in reply to 109517
Sorry, in the case of step being larger then value,you are right. Its
late here :) But it could be smaller, so personally I wouldn't write an
if, but I defenetly wouldn't loop!

Re: [CodeSOD] Fun with Maths

2007-01-03 17:14 • by GeneWitch
109525 in reply to 109519
Anonymous:

value is 23
increase value by 1
while value mod 500 is not equal to 0 --> increase value by 1

 

Now read this slowly. 

OK.

Imports system.IO
Imports System.Console
Imports System.Math
Module Module1

    Sub Main()
        Dim _step As Integer = 500
        Dim value As Integer = 23
        Dim counter As Integer = 0

        While ((value Mod _step) > 0)
            counter = counter + 1
            value = value + 1
        End While

        WriteLine(value)
        WriteLine(_step)
        WriteLine(counter)
        Read()

    End Sub

End Module

This outputs:

500
500
477

Read above... My statement was not incorrect, i just assumed that the original programmer couldn't have been so stupid as to have made the variable "step" larger than the variable "value" everything i said regarding the step>value was 100% correct, except that i assumed it wanted the NEXT larger value. which would mean 1000, in this case. 477 iterations.

Re: [CodeSOD] Fun with Maths

2007-01-03 17:30 • by someone else thinking someone is funny
109531 in reply to 109519

hehe hehehe...  kewl.

 

Re: [CodeSOD] Fun with Maths

2007-01-03 18:22 • by Jheriko
109545 in reply to 109515

If value%step is zero then value+=step-(value%step); has the same effect as value+=step; hence your elseif is redundant.

I will concede that your if(step > value) is more efficient in that it dodges the modulus operator, however I did point out that the code I (and others) provided is the trivial solution. By singling out a special case yours has become non-trivial. The point being that even a novice should be able to work out "value+=step-(value%step);" with little to no thought. For a paid programmer to implement a loop... he needs to have his hands removed so that he can never write code again!

My code performs exactly the same function as yours otherwise. Just to stress the point, if step is greater than, less than or equal to value the single line I provided still works.

Anyway... you don't really have to use capital letters that much, especially when there are buttons provided to help you format things in other, more attractive ways. Also, please try to spell my name correctly, there really is no excuse when it has been spelled for you at the top of the quote.

 

Re: [CodeSOD] Fun with Maths

2007-01-03 18:29 • by Jheriko
109547 in reply to 109545

The quote seemed to not appear... despite being prominently visible whilst writing the post :/

 

I was refering to GeneWitch and his code and comments posted above:

 

Quote: 

So if i come up to you, and i say, hey, jherico... the number 25000!
what's the next value that is divisible by 25000 - You'd pull out a
modulo operator? the variable "value" in the code snippet above is
being INCREMENTED BY ONE. In ALL cases where Step is larger than value,
the answer is either value=step OR value=step*2 (depending on wtf they
were using it for).

Otherwise (assuming what everyone up until this point has understood, that you want to find the next VALUE divisible by step)

if (step>value)

     value=step //or for whatever reason value = step * 2 

elseif (value%step = 0) then

     value +=step

else

value = value + (step - (value%step)) //as jherico said

endif

 

Re: [CodeSOD] Fun with Maths

2007-01-03 18:50 • by doynax
109551 in reply to 109465

Anonymous:

It's worse than that, because if the example is in Java or C# or any other language which copied the deranged '%' behavior from C, then *all* of the replacements, including yours, break for negative numbers. (% isn't really modulus, it's remainder-after-integer-division-that-rounds-toward-zero.)

This isn't really C's fault, if anyone is to blame it's the processor designers. Whether integer division and modulo round towards zero or
negative infinity is implementation defined, the language simply
mirrors whatever your processor actually does to avoid costly
workarounds on "odd" processors.
This is (at least some of the reason) why there's a div() function, it's guaranteed to round towards zero.

Re: [CodeSOD] Fun with Maths

2007-01-03 19:10 • by Tom Dibble
109558 in reply to 109515
GeneWitch:
Jheriko:

Either this is all some kind of joke, or you mostly fail at solving trivial problems.


To get the to the next value divisble by step you only need to add the difference in the modulus from step

value += step - (value%step);


There are probably faster and nicer ways. This is just the trivial solution.

Some of you mentioned this already and other ignored it... which is even more of a WTF. How hard is reading a thread before posting your crap? 

So if i come up to you, and i say, hey, jherico... the number 25000! what's the next value that is divisible by 25000 - You'd pull out a modulo operator? the variable "value" in the code snippet above is being INCREMENTED BY ONE. In ALL cases where Step is larger than value, the answer is either value=step OR value=step*2 (depending on wtf they were using it for).

Otherwise (assuming what everyone up until this point has understood, that you want to find the next VALUE divisible by step)

if (step>value)

     value=step //or for whatever reason value = step * 2 

elseif (value%step = 0) then

     value +=step

else

value = value + (step - (value%step)) //as jherico said

endif


Okay, but:

1.  You now have three separate cases to test.  And, of course, you haven't handled a negative value.
2.  "All that voodoo" is both easy to comprehend and incredibly fast for the computer to process.  Easier than a bunch of test/jumps.
3.  Assuming that we're not starting at 0 and incrementing "value" to each "step" above, real data would hit the third case much more often than either of the previous.  If we get to the third case, the processor has done the modulo twice instead of once, completely negating any performance benefit you might be expecting with a really expensive modulo operator.

IMHO, the more efficient code is:

assert (value>=0) // This is probably a valid assertion.  I can't think of a case doing this where you wouldn't be dealing with positive values!
assert (step > 0) // for safety:  x%0 is undefined, and negative step value is unlikely to be anything other than an error
value += step - (value%step)

NOTE:  the following assumes Flash % operates similarly to Java/C99 % (and not as C89 %, in which it was completely undefined for negatives!)

If the first assertion does not hold out (ie, there is a way to get value < 0 to the function) then adjust as follows:

value += ( value < 0 ? 0-(value%step) ) : step - (value%step) )

(example:  -15 and 7:  -15 % 7 works out to -1.  value = -15 + (0- -1) = -15 + 1 = -14)

See explanation closing "bug" in Java here:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4639626


IF Flash would always yield a positive modulo value (ie, "-15 % 7 == 6"), then you would be just fine with the original code (just remove the value >= 0 assertion):

value += step - (value%step)

(example:  -15 and 7:  -15 % 7 would be 6.  value = -15 + (7 - 6) = -15 + 1 = -14)

There is (for good reason) much ambiguity around the modulo/remainder operator and negative operands.  If you have to handle negatives (especially in the 'step'), you will often need significantly more complex code, as above.  This complexity introduces likelihood of bugs as well as additional necessary tests.  At that point, the brute-force code of the original WTF starts to look pretty good!


Re: [CodeSOD] Fun with Maths

2007-01-03 19:12 • by GeekMessage
109560 in reply to 109519
someone:
value is 23

increase value by 1

while value mod 500 is not equal to 0 --> increase value by 1

 Now read this slowly.

Okay,
I got to about value == 27,  then I got bored and wandered
off.  Now I'm trying to catch up with my computer, which got bored
somewhat earlier, but I can still see it in the distance...

Re: [CodeSOD] Fun with Maths

2007-01-03 19:32 • by Tom Dibble
109562 in reply to 109465
Anonymous:

It's worse than that, because if the example is in Java or C# or any other language which copied the deranged '%' behavior from C, then *all* of the replacements, including yours, break for negative numbers. (% isn't really modulus, it's remainder-after-integer-division-that-rounds-toward-zero.)

So a fixed version is:

down_value = value - ((value % step + step) % step)

up_value = value - ((value % step + step) % step) + step


IMHO, there's not much concensus on what a "non-deranged" modulo behavior should be in the case of negative dividends and divisors.  C99 defines it one way, ADA as another.  Although, if you pronounce "%" as "remainder" instead of "modulo" as Java would have you do, then C99, Java, and ADA are all in line (ADA having both mod and rem operators).

http://en.wikipedia.org/wiki/Modulo_operation


In any case, I'd much rather to an if-branch on the negative value case than modulo twice.  Wouldn't that always be both more efficient and less likely to give me a headache?  (okay, don't answer the latter, I already know its answer).


« PrevPage 1 | Page 2Next »

Add Comment