It is currently February 23rd, 2024, 3:47 am

[BUG] Division by 0 in the false branch of numerical conditionals

Report bugs with the Rainmeter application and suggest features.
User avatar
Yincognito
Rainmeter Sage
Posts: 6781
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: [BUG] Division by 0 in the false branch of numerical conditionals

Post by Yincognito »

Brian wrote: December 17th, 2023, 8:11 am Rainmeters MathParser works by evaluating the left and right tokens of an operation...in order of precedence. It just so happens that the ternary operator considers the left and right tokens to be "parameters" of the operation, so it evaluates both of the tokens before the operation.

I might be able to fix this, however, the math parser was written by a 3rd party many years ago, and it is quite fragile (not to mention complex).

-Brian

Bonus points! I just found a new operator, although I am not sure of its usefulness. It's the $ operator. If the left token is less than or equal to 0, it returns 0. If the right token is 0, it prints an error (Division by 0). Otherwise it returns ceil(left / right). I have no idea why this is there, or what to even call it. :confused:
https://github.com/rainmeter/rainmeter/blob/master/Common/MathParser.cpp#L564-L577
Now that a perfectly valid epsilon like workaround is feasible due to how Rainmeter has a maximum decimal precision of 5, fixing this has lost its urgency (at least for me), but one day it should be done, since the valid branch never gets chosen because of the unchosen invalid one in similar cases.

One way to fix it, if the test is evaluated first, would be to always allow the token corresponding to the numerical 0 or 1 value of the boolean test to be invalid for conditionals, since this always represents the ordinal number of the branch that neither is nor it influences the conditional result. Or, just turn the C++ conditional at line 610 in the parser (to which the Rainmeter conditional is "translated" to, as mentioned earlier) into a plain if..else statement, thus using only one of the tokens (corresponding to the boolean value of the test) as the value of the res variable and making the result always have a value if the chosen token is valid, which is the whole point of this thread (sorry if it seemed like suggesting that the point was the short circuit). I'm just guessing here, of course, I'm by no means an expert in C++ or Rainmeter's math parser - just trying to help the best way I can. :confused:

As for the $ operator, UNK probably comes from unknown, but it could be called the natural ceiling division operator based on its behavior (don't think it's the same as negating the Python's // operator though, which produces plain ceiling division). It might have practical applications though, since it basically tells how many arbitrarily sized trucks are needed to load an arbitrary quantity of cargo completely (might as well call it the truck operator, since it's truck number = cargo quantity $ truck capacity, and $ come out of a successful delivery, lol). Any negative or non existing quantity would take no trucks (hence 0), of course, if the trucks have no trailer being in the business is pointless (hence error), and for any leftover cargo after fully loading some trucks another truck would be needed (hence ceiling).
Dang, now I need to play some ETS2 to get the feeling of this bonus operator... :D
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth