ID:264426
 
Code:

        if(inp=="Dagger Blade")
var/obj/Items/Materials/Dagger_Blade/S=new(M.loc)
S.Quality=quality
O.BaseWeight-=0.4
O.Weight=O.BaseWeight
S.name="[QualityToText(quality)] [O.Material] [S]"
S.Material=O.Material
if(O.BaseWeight<=0) del O



if(inp=="Rod")
var/obj/Items/Materials/Rod/S=new(M.loc)
S.Quality=quality
O.BaseWeight-=1
O.Weight=O.BaseWeight
S.name="[O.Material] [S]"
S.Material=O.Material
if(O.BaseWeight<=0) del O


Problem description:

Compare the above two sections of code, for most instents and purposes, they are exactly the same. To the point where they were literally copied and pasted, and are part of the same proc.

Here is the good part.
The "Rod" item is crafted from a log with a weight of 10. When you craft 10 rods, the log is destroyed (nothing left of it).
The "Dagger Blade" item is crafted from a metal bar, with a weight of 4. Once 10 are crafted, it SHOULD be destroyed, but it is not, instead it's weight apparently becomes some random, crazy number, like 1.19209e-007.
Everything works FINE, up until the metal bar should be destroyed.

This happens with every item that is crafted from a metal bar.

For all intents and purposes, there is no different between the objects Log and Metal Bar, except for the three variables Weight, BaseWeight and Material.
Similarly, there is no different between a rod and dagger blade except for the above 3 variables.

I can eliminate the variable Material by making them both the same.

Can anyone explain just what this madness is? How the hell is BYOND failing at basic math?
Chances are something is being changed elsewhere, or I'm missing something. It appears that you're dividing somewhere, or something; there are many decimal places in the number, so its possible that you're dividing 10 times somewhere on accident.

Also, what's the point of Weight if its always going to be set to BaseWeight? BaseWeight, if it represents the original weight, shouldn't change, while Weight should, amirite? Or is that just a confusing variable name?
Wow, that is a very, very odd BYOND bug. "1.19209e-007" isn't a random number, it's 1.19209x10-7 (or .000000119209), which is pretty close to zero. I'm amazed no one has found this before* :/

I doubt there's an easy way for the devs to fix it, though, and seems to happen with a wide range of numbers.

var/a = 1.2
a-=0.4
a-=0.4
a-=0.4
world<<a //outputs 5.96046e-008


An easy fix for you would be round BaseWeight to the nearest tenth or hundredth place:

O.BaseWeight=round(O.BaseWeight-0.4,0.1)



*I'm sure someone knows about it, but I would report it anyways
In response to DarkCampainger
DarkCampainger wrote:
I doubt there's an easy way for the devs to fix it, though, and seems to happen with a wide range of numbers.

This appears to happen with any decimal subtraction if it is repeated more than 2 times to reach zero.

I.E:
var/Base=0.2
var/Subtract=0.1
while(Base>=0)
Base-=Subtract
world<<"[Base] ([round(Base,0.1)]"

This will output appropriately, but if you change Base to 0.3 it will glitch. Same with 0.8 base 0.4 subtract, etc etc etc.

(In my previous post I said rarely is it actually an error in the program and usually it is operator error. But yea lol. Apparently this was one of those "rarely" times.)


EDIT: The same applies when you throw in divison and other mathematics as long as the last thing you do is 3 subtractions or more in a row.
Example:
mob/verb/Test2()
var/Base=3.2

Base/=2
while(Base>0)
Base-=0.4
world<<Base
0.4 is an infinitely repeating number in binary (0.011001100...), so you simply have a rounding error. This is equivalent to subtracting 1/3 from 1 three times, with some number of digits of precision:
1.00 - 0.33 - 0.33 - 0.33 = 0.01
It is not the fault of BYOND and the same error would occur in any other language. Just use round() after every subtraction, or deal exclusively in integers.
In response to Garthor
Garthor wrote:
0.4 is an infinitely repeating number in binary (0.011001100...), so you simply have a rounding error. This is equivalent to subtracting 1/3 from 1 three times, with some number of digits of precision:
1.00 - 0.33 - 0.33 - 0.33 = 0.01
It is not the fault of BYOND and the same error would occur in any other language. Just use round() after every subtraction, or deal exclusively in integers.

Then why would this happen with 0.1 as well? And 0.3... and 0.2...
In response to AJX
Because they are all infinitely repeating numbers in binary. 0.25 (and multiples), for example, are not.
In response to Garthor
Wow, I never thought of how binary would handle decimal places. I'm guessing there are a lot numbers it has trouble with :P

Also, welcome back Garthor! Haven't seen you around in ages!
In response to Garthor
Wow, I haven't seen you in a while. Welcome back!