DepravityExtended Posted November 13, 2018 Posted November 13, 2018 So I'm getting this weird thing where my script wont divide right. When I divide any number that would return as a decimal it returns as 0.000. Script: Function UpdateHumiliation() float humiliation if recentmemory > 0 miscutil.printconsole("Fotd: Complex Humility check triggered") ;humiliation = math.floor(((recentMemory/Break)*100)*(CurrentEvent/RecentMemory)) elseif recentmemory < 1 miscutil.printconsole("Fotd: simple Humility check triggered") Humiliation = 90/100 ;(100*(Currentevent/break)) utility.wait(2.0) playerref.setfactionrank(FotdHumiliationPerk, Humiliation as int) miscutil.printconsole("Fotd: RecentMemory: "+RecentMemory) miscutil.printconsole("Fotd: current Memory: "+CurrentEvent) miscutil.printconsole("Fotd: Break: "+Break) debug.notification("Humiliation is: "+Humiliation) endif endfunction Anyone know whats up?
Nazzzgul666 Posted November 13, 2018 Posted November 13, 2018 Uh, not very familiar with papyrus but if recentmemory > 0 elseif recentmemory < 1 screams "bug" to me. Assuming it's always a value between 0 and 1, both conditions are always true, i'm not sure how papyrus handles that? I guess it'll process both, one after another. And if recentmemory isn't always between 0 and 1, it doesn't do anything. *edit: that would be another problem, though. The reason for your "returns zero" is that 90/100, then casting it to int if i get the code right.
Holzfrau Posted November 13, 2018 Posted November 13, 2018 1 hour ago, CPU said: Humiliation = 90.0/100.0 Assuming you don't have a programming background here, let's break this down further: Papyrus, like many programming languages, can handle numbers in two different ways. Floating point, which is a binary implementation of scientific notation, is used for numbers that could have any value. Values which will only be treated as whole numbers, integers, are truncated - anything after the decimal point is chopped off. When you divide numbers, the divisor (second number) determines how the result will be stored. In your example, you have 90 (integer) divided by 100 (integer). The result of 0.9 is converted to an integer type because the divisor specifies it as such - the decimal value is chopped off and it becomes a whole number, 0. In addition to CPU's correction, any of the following lines will give the same result, because they all specify the divisor, and therefore the result, to be floating point: 90/100.0 90/(float)100 0x5a/100.0 ; That's 90 in hexadecimal. How you write the dividend has no bearing on how the result is treated! Just be careful not to fall into the trap of (float)(90/100) - that will calculate 90 (as an integer) divided by 100 (as an integer) like you had. By the time the script tries to cast the result to a floating point value, it is already 0.
TanookiTamaTachi Posted November 13, 2018 Posted November 13, 2018 1 hour ago, Holzfrau said: Assuming you don't have a programming background here, let's break this down further: Papyrus, like many programming languages, can handle numbers in two different ways. Floating point, which is a binary implementation of scientific notation, is used for numbers that could have any value. Values which will only be treated as whole numbers, integers, are truncated - anything after the decimal point is chopped off. When you divide numbers, the divisor (second number) determines how the result will be stored. In your example, you have 90 (integer) divided by 100 (integer). The result of 0.9 is converted to an integer type because the divisor specifies it as such - the decimal value is chopped off and it becomes a whole number, 0. In addition to CPU's correction, any of the following lines will give the same result, because they all specify the divisor, and therefore the result, to be floating point: 90/100.0 90/(float)100 0x5a/100.0 ; That's 90 in hexadecimal. How you write the dividend has no bearing on how the result is treated! Just be careful not to fall into the trap of (float)(90/100) - that will calculate 90 (as an integer) divided by 100 (as an integer) like you had. By the time the script tries to cast the result to a floating point value, it is already 0. I don't think that is entirely correct. 90.0 / 100 should still return 0.9, even if in that case it is the left-hand side that is a float. As long as either one of the operators is a float, the result should be a float. At least. that was the case in pretty much any language I've ever used.
Holzfrau Posted November 13, 2018 Posted November 13, 2018 17 minutes ago, TanookiTamaTachi said: I don't think that is entirely correct. 90.0 / 100 should still return 0.9, even if in that case it is the left-hand side that is a float. As long as either one of the operators is a float, the result should be a float. At least. that was the case in pretty much any language I've ever used. Just tested this, and you are correct. Moral of the story is to not throw two integers into the division calculation!
Tyrant99 Posted November 13, 2018 Posted November 13, 2018 Yes, long story short, float == decimals, int == whole numbers, be careful how you mix them. And I think (float)(90/100) evaluates to float in most languages: Python at least:
Guest Posted November 13, 2018 Posted November 13, 2018 8 minutes ago, Hugh Reckum said: Yes, long story short, float == decimals, int == whole numbers, be careful how you mix them. And I think (float)(90/100) evaluates to float in most languages: Python at least: This is because the divide operator of Python automatically converts the numbers to floats.
Tyrant99 Posted November 13, 2018 Posted November 13, 2018 41 minutes ago, CPU said: This is because the divide operator of Python automatically converts the numbers to floats. Ahh, true enough, Java then: But order of operations from parens does make a difference. Anyway, moral #2, stay away from ambiguous shit when you script. Can't really go wrong with (90.0 / 100) no matter what language you're in.
Guest Posted November 13, 2018 Posted November 13, 2018 1 hour ago, Hugh Reckum said: Ahh, true enough, Java then: ... In your Java example you are casting just the first number to float. Casting has the precedence over operators in Java. If you first divide (because you put the operator in parentheses) you get 0 as result, then you cast it to float and you get 0.0
Tyrant99 Posted November 13, 2018 Posted November 13, 2018 8 minutes ago, CPU said: In your Java example you are casting just the first number to float. Casting has the precedence over operators in Java. If you first divide (because you put the operator in parentheses) you get 0 as result, then you cast it to float and you get 0.0 Yes, I saw that. My point was, it's better to script in a way (when possible) where it doesn't matter what the programming language does with its operators. Python automatically converts the divide operator to float, whereas Java doesn't, + Java takes order of operations precedence. But (90.0 / 100) will produce the intended float with either language, so I'd prefer that method as it's clearer and involves less messing around with syntax and programming language nuances.
Guest Posted November 13, 2018 Posted November 13, 2018 14 minutes ago, Hugh Reckum said: Yes, I saw that. My point was, it's better to script in a way (when possible) where it doesn't matter what the programming language does with its operators. Python automatically converts the divide operator to float, whereas Java doesn't, + Java takes order of operations precedence. But (90.0 / 100) will produce the intended float with either language, so I'd prefer that method as it's clearer and involves less messing around with syntax and programming language nuances. In many cases 90.0/100.0 is faster than 90.0/100 or 90/100.0 This because there is no need to convert an int to a float, the values are stored already as floats, so one conversion less.
Tyrant99 Posted November 13, 2018 Posted November 13, 2018 38 minutes ago, CPU said: In many cases 90.0/100.0 is faster than 90.0/100 or 90/100.0 This because there is no need to convert an int to a float, the values are stored already as floats, so one conversion less. Sure, 90.0/100 was just an example from earlier in the thread, but it still represented a more universal approach than other alternatives. Cleanest, fastest, simplest, most comprehensible, most universal way is best imo.
Nazzzgul666 Posted November 13, 2018 Posted November 13, 2018 Rather out of curiosity than related to OP's problem: how is his if >0 else if <1 handled? Assuming the value is 0.5, would papyrus execute both, one after another or what else? It's been a while since i did some coding and my feeling that this looks strange might be wrong, is it?
Holzfrau Posted November 13, 2018 Posted November 13, 2018 9 minutes ago, Nazzzgul666 said: Rather out of curiosity than related to OP's problem: how is his if >0 else if <1 handled? Assuming the value is 0.5, would papyrus execute both, one after another or what else? It's been a while since i did some coding and my feeling that this looks strange might be wrong, is it? It would only execute the stuff from the first if. As you pointed out earlier in the thread, it is almost certainly a bug.
Nazzzgul666 Posted November 13, 2018 Posted November 13, 2018 4 minutes ago, Holzfrau said: It would only execute the stuff from the first if. As you pointed out earlier in the thread, it is almost certainly a bug. Thanks, good to know that my feeling isn't entirely wrong.^^ Still wondering though... if you're right and only the first if is executed, it shouldn't be possible to reach that 90/100 part ever.
Holzfrau Posted November 13, 2018 Posted November 13, 2018 2 minutes ago, Nazzzgul666 said: Thanks, good to know that my feeling isn't entirely wrong.^^ Still wondering though... if you're right and only the first if is executed, it shouldn't be possible to reach that 90/100 part ever. It would still hit the 90/100 part if recentmemory is <= 0.
Nazzzgul666 Posted November 13, 2018 Posted November 13, 2018 Just now, Holzfrau said: It would still hit the 90/100 part if recentmemory is <= 0. Oh, right.^^ Not sure why i was thinking the value it gets is between 0 and 1.
DepravityExtended Posted November 13, 2018 Author Posted November 13, 2018 8 hours ago, Nazzzgul666 said: Uh, not very familiar with papyrus but if recentmemory > 0 elseif recentmemory < 1 screams "bug" to me. Assuming it's always a value between 0 and 1, both conditions are always true, i'm not sure how papyrus handles that? I guess it'll process both, one after another. And if recentmemory isn't always between 0 and 1, it doesn't do anything. *edit: that would be another problem, though. The reason for your "returns zero" is that 90/100, then casting it to int if i get the code right. The recentmemory can be higher than 1, and I forgot to add as int again before copy pasting the code. XD I removed the checks to test and it still resulted in 0.0 As far as everyone elses responses, they didn't work D:. Things tried: changed 90/100 to 90.0/100.0 resulted 0.0 changed 90/100 to 90/100.0 resulted 0.0 changed 90/100 to (90/100.0) as float resulted 0.0 added 'as float' to the debug.notification, felt kinda pointless but gotta try everything... Still showed 0.0
Holzfrau Posted November 13, 2018 Posted November 13, 2018 13 minutes ago, SkyLover37 said: The recentmemory can be higher than 1, and I forgot to add as int again before copy pasting the code. XD I removed the checks to test and it still resulted in 0.0 As far as everyone elses responses, they didn't work D:. Things tried: changed 90/100 to 90.0/100.0 resulted 0.0 changed 90/100 to 90/100.0 resulted 0.0 changed 90/100 to (90/100.0) as float resulted 0.0 added 'as float' to the debug.notification, felt kinda pointless but gotta try everything... Still showed 0.0 Can you post what the function looks like now? All 3 of the changes you made should be giving you a floating point result. Another thing you can try is a clean save where your mod will be applied for the first time again, just to be certain something isn't 'stuck' in Papyrus.
DepravityExtended Posted November 13, 2018 Author Posted November 13, 2018 Fucking. Hell. My forgetfulness will be the death of me. changing 100 to 100.0 DID work! Thanks guys! I forgot I moved the code to another script for some reason, so the changes I made weren't even being run... -.- Edit: All the posts here were also super interesting and helpful, so thanks for that too.
Nazzzgul666 Posted November 13, 2018 Posted November 13, 2018 48 minutes ago, SkyLover37 said: The recentmemory can be higher than 1, and I forgot to add as int again before copy pasting the code. XD I removed the checks to test and it still resulted in 0.0 As far as everyone elses responses, they didn't work D:. Things tried: changed 90/100 to 90.0/100.0 resulted 0.0 changed 90/100 to 90/100.0 resulted 0.0 changed 90/100 to (90/100.0) as float resulted 0.0 added 'as float' to the debug.notification, felt kinda pointless but gotta try everything... Still showed 0.0 Seems still a bit fishy to me, but i admit i might be wrong. There are possible scenarios where this way might make sense, but it's still hard to read and i'd try to avoid it just for readability. As mentioned, i'm not familiar with papyrus but as far as i can see the first condition is always true and will always be executed (except recentmemory is <0). How i'd actually expect if-else if is as if $var>1 do that else if $var>0 do this else ;if negative and that's not expected printconsole ("a dragon vomited in your code") That way, every possibility would be covered and obvious. You know where you get recentmemory get from and which values are to expect, but i can't see that and as far as i know, the entire code snipped might just be skipped because recentmemory is either <=0 or >=1, which might be one reason the value for humilation is zero. For the whole division thing... not sure why you even do it, to test how it works? If i wanted $humilation to be 0.9, i'd write $humilation = 0.9 ^^ 28 minutes ago, SkyLover37 said: Fucking. Hell. My forgetfulness will be the death of me. changing 100 to 100.0 DID work! Thanks guys! I forgot I moved the code to another script for some reason, so the changes I made weren't even being run... -.- Edit: All the posts here were also super interesting and helpful, so thanks for that too. Took me ages to write that comment, was sniped. And yes... that happens.^^ *edit: just to be clear, i don't mean you should write your code in a way i can read it. I most likely won't.^^ But adding comments and maintain a general readability will help YOU. Right now you know what you're trying to do, but every coder who had a look on code s/he wrote a year or two ago is grateful for any help to understand the own code. Trust me on this.
DepravityExtended Posted November 13, 2018 Author Posted November 13, 2018 1 hour ago, Nazzzgul666 said: That way, every possibility would be covered and obvious. You know where you get recentmemory get from and which values are to expect, but i can't see that and as far as i know, the entire code snipped might just be skipped because recentmemory is either <=0 or >=1, which might be one reason the value for humilation is zero. For the whole division thing... not sure why you even do it, to test how it works? If i wanted $humilation to be 0.9, i'd write $humilation = 0.9 ^^ The 90/100 was indeed to figure out why I was receiving a 0. And your right, I should add another catch in case something goes wrong, thanks
Recommended Posts
Archived
This topic is now archived and is closed to further replies.