Jump to content

Papyrus not dividing correctly.


Recommended Posts

Posted

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?

Posted

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.

Posted
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.

Posted
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.

Posted
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!

Posted

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:

image.png.6bc52f623ac20f33660aed8a4cb19775.png

Posted
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:

image.png.6bc52f623ac20f33660aed8a4cb19775.png

This is because the divide operator of Python automatically converts the numbers to floats.

Posted
41 minutes ago, CPU said:

This is because the divide operator of Python automatically converts the numbers to floats.

Ahh, true enough, Java then:

 

image.png.3116a8d16ca89cfadae0700e9b7100d6.png

image.png.6724df036eb8f971b5ffc4de0b0f4602.png

 

But order of operations from parens does make a difference.

 

image.png.4e875b6848c8b7377a3485104ededd3e.png

image.png.7232a00d9ebafa430773703faa4242ae.png

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.

 

Posted
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

Posted
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.

Posted
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.

Posted
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.

Posted

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?

Posted
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.

Posted

 

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.

Posted
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.

Posted
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

Posted
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.

Posted

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. :D

Posted
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. :D

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. ;)

Posted
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 :D

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...