Bug - Not A Bug CEIL function not working correctly

ElCarrot

New member
I'm trying to calculate how many milk of magnesium's I need to use, so I use the calculation
int numMilk = ceil((fullness_limit() - my_fullness()) / 15);

In my testing, I ended up with 1 fullness, for a calculation of:

ceil(14/15)

This returns back 0

As a float - this is 0.933 repeating, so shouldn't this return back 1?

I tested this in the 11511 build of mafia.

Thanks
 

Catch-22

Active member
Not a bug. You're correct, as a float that's 0.933, but as integer operations 14/15 = 0, ceil(0) = 0.

Try:
int numMilk = ceil((fullness_limit() - my_fullness()) / 15.0);
 

Theraze

Active member
Or follow 'standard' operations and turn your initial number into a float manually...
Code:
int numMilk = ceil(to_float(fullness_limit() - my_fullness()) / 15);
 

Bale

Minion
I'm going to have to side with Catch-22 here. Dividing by 15.0 is much easier to read and does not require an extra operation. WTF is "standard" about converting the first number to a float?
 

Fluxxdog

Active member
The original script is buggy to begin with. Dividing by 15 is incorrect. It should be divided by the number of turns of the effect granted by MoM. You don't get 15 turns unless you have Impetuous Sauciness, something which you're denied in Boriscore or Zombiecore. It should be coded as:
Code:
int numMilk = ceil((fullness_limit() - my_fullness())/numeric_modifier($item[milk of magnesium],"Effect Duration"))
And since numeric_modifier() returns a float value, everything falls in line. I'd heartily suggest you take a look at this post for more explanations of numeric_modifier(). It's a treasure trove of goodyness. (Which is now a thing ^^)

If by 'standard' you mean 'less concise', sure.
Simply using 15.0 is less concise as it's not made clear why 15.0 is being used instead of "mathematically correct" 15. to_float() makes it obvious you're forcing floats. Otherwise, you'd need a comment saying "//15.0 used to force floats".

Using 15.0 would be terse.
 

Winterbay

Active member
The original script is buggy to begin with.

Not necessarily. That would depend on what scope the script is intended to fulfil. It's only a bug if it is intended to be used under zombie or boris and similar and with variable characters, if not then just using 15 is much easier.
 

Catch-22

Active member
Not necessarily. That would depend on what scope the script is intended to fulfil. It's only a bug if it is intended to be used under zombie or boris and similar and with variable characters, if not then just using 15 is much easier.

This is exactly why I didn't go into any more detail than what was necessary.

People can feel free to do extraneous data type conversions, if that's what makes them happy. Do it your own way, it's not my script so I don't care which way it's done. I just think it's a little naïve to call something the "standard" way, there's no governing body when it comes to getting things done in ASH.

OP's issue should be well and truly resolved by now, which is the main reason we are here. If anyone would like me to explain why the way Bale and I would do it is more efficient, I would be happy to do so (though Bale pretty much hit the nail on the head). Otherwise, let's just say "you've got your way, I've got mine", they both get the job done.
 

Theraze

Active member
At some point in my C programming days came the caution that if you wanted an equation to be done as a float, convert the first number to a float explicitly. The rest will follow.
> ash ((15.0/4)/2)

Returned: 1.875

> ash ((to_float(15)/4)/2)

Returned: 1.875

> ash ((15/4)/2)

Returned: 1

> ash (to_float(15/4)/2)

Returned: 1.5

> ash ((15/4.0)/2)

Returned: 1.875
Whether you explicitly cast 15.0 as a static float or convert an int variable to a float, do it first, to the single variable, and you'll scratch your head at the math less later. Yes, if you want to put it in later at the first point where you know there will be a float required, that's fine... but harder for someone else to look through and know what you did and why later. It is definitely more concise... 2 characters over (in ASH) 10.

That being said, in this single example, we're dealing with appetite ints, so converting the ending divisor is fine, since that's the first place where we can reasonably expect to see a float emerge. :)
 

heeheehee

Developer
Staff member
The original script is buggy to begin with. Dividing by 15 is incorrect. It should be divided by the number of turns of the effect granted by MoM. You don't get 15 turns unless you have Impetuous Sauciness, something which you're denied in Boriscore or Zombiecore. It should be coded as:
Code:
int numMilk = ceil((fullness_limit() - my_fullness())/numeric_modifier($item[milk of magnesium],"Effect Duration"))
And since numeric_modifier() returns a float value, everything falls in line. I'd heartily suggest you take a look at this post for more explanations of numeric_modifier(). It's a treasure trove of goodyness. (Which is now a thing ^^)

For conciseness...
Code:
modifier_eval("ceil((" + fullness_limit() + "-F)/(R+5))")

Of course nobody codes that way, right? :p
 

ElCarrot

New member
The original script is buggy to begin with. Dividing by 15 is incorrect. It should be divided by the number of turns of the effect granted by MoM. You don't get 15 turns unless you have Impetuous Sauciness, something which you're denied in Boriscore or Zombiecore. It should be coded as:
Code:
int numMilk = ceil((fullness_limit() - my_fullness())/numeric_modifier($item[milk of magnesium],"Effect Duration"))
And since numeric_modifier() returns a float value, everything falls in line. I'd heartily suggest you take a look at this post for more explanations of numeric_modifier(). It's a treasure trove of goodyness. (Which is now a thing ^^)

Simply using 15.0 is less concise as it's not made clear why 15.0 is being used instead of "mathematically correct" 15. to_float() makes it obvious you're forcing floats. Otherwise, you'd need a comment saying "//15.0 used to force floats".

Using 15.0 would be terse.

Thanks to everyone for the verbose explanation - I hadn't even considered many of the points made. I will be adding Fluxxdog's superior version of the calculation to my code.
 
Top