intfiction.org

The Interactive Fiction Community Forum
It is currently Fri Feb 22, 2019 12:18 am

All times are UTC - 6 hours [ DST ]




Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Mon Jan 03, 2011 3:28 am 
Offline
User avatar

Joined: Mon Oct 04, 2010 11:35 am
Posts: 876
Location: Toronto
Knocking around the UNITS system trying things, I've found at least two (seemingly, different) problems with Inform's built-in math routines. The answer Inform gives is actually not mathematically correct. These are problems with very common operations like simple multiplication and even addition, so I would be surprised if these are not already known issues, thus I have not reported them yet as bugs and have been thinking about them for about a week wondering if I just miscalculated something, but I don't think so. Math is math...

Both issues are with Inform's system of fractional math. The first occurs when you simply scale a number with a non-base-10 value. For example...

Code:
The Kitchen is a room. Filesize is a kind of value. 1KB specifies a filesize. 1MB specifies a filesize scaled up by 1024.

X, Y, and Z are filesizes that vary.

X is 500KB. Y is 700KB.

When play begins:
   showme x;
   showme y;
   now z is x + y;
   showme z;
   now z is z - 700KB;
   showme z.

The first value returned for Z is off -- it returns 1.1729MB when the answer should be 1.1719MB -- and the error is larger by an order of magnitude than the margin of error you would expect from the scaling (I would expect the 4th decimal place to possibly be wrong or omitted, but not the third, that's too much error). However, it seems the value is being stored correctly, because subtracting 700KB from Z results in the correct value, so the mistake only appears when printing a scale-shifted result (and furthermore only when printing a result scale-shifted via a non-base-10 scale).

The other flaw is much simpler and I'd be surprised if people didn't know about it already. Multiplying and dividing compound units (i.e. '6 foot 2' or '8 lb 5 oz') by each other produces results that are way off, usually by an order of magnitude -- and the whole number, not just one digit. Witness the disastrous results of my attempt to create an (apparently) unitless, single-decimal-place number type...

Code:
The Kitchen is a room. A single-decimal-place number is a kind of value.
1.9 specifies a single-decimal-place number with parts integer and decimal.
A single-decimal-place number times a single-decimal-place number specifies a single-decimal-place number.

When play begins:
   let p be 1.9;
   let q be 7.5;
   let r be p * q;
   let s be p / q;
   showme r;
   showme s.

Multiplication inflates the results when multiplying compound units together, in this case by a factor of 10. Division lowballs the result by a factor of I think either 100 or 1000 in this case; though I don't remember specifically -- you can probably work it out from the 'To decide' routine I ended up with to compensate (see below).

I was finally able to create a somewhat mathematically usable, compound unit, but after correcting for Inform's errors, it isn't exactly pretty. With multiplication it was easy: I just fudged it. With division the necessary precision gets lost, so the only way was to convert the whole thing to integer math and then back again (but something janky seems to be going on there, too, because I had to scale the dividend up by an order of magnitude more than I expected, to get the right answer out even using integer math, or maybe I just miscalculated at first, but anyway by trial & error, I basically just added factors of 10, until I got the right answer).

The below will probably have to be modified to compensate for a different level of error if you use non-base-10 scaling or if want greater than one decimal place of precision, but these additional 'To decide' routines or something like them seems necessary to get accurate co-multiplication or co-division out of a compound (i.e. two part) unit kind: please correct me if I am wrong...

Code:
The Kitchen is a room.
   
A single-decimal-place number is a kind of value.
1.9 specifies a single-decimal-place number with parts integer and decimal.
A single-decimal-place number times a single-decimal-place number specifies a single-decimal-place number.
   
   To decide which single-decimal-place number is (x - a single-decimal-place number) multiplied correctly by (y - a single-decimal-place number):
      let z be x * y;
      decide on z / 10.
   
   To decide which single-decimal-place number is (x - a single-decimal-place number) divided correctly by (y - a single-decimal-place number):
      let xk be 10 * the integer part of x;
         now xk is xk + the decimal part of x;
         now xk is xk * 100;
      let yk be 10 * the integer part of y;
         now yk is yk + the decimal part of y;
      let zk be xk / yk;
         now zk is zk / 10;
      let zi be zk / 10;
      let zd be the remainder after dividing zk by 10;
      decide on the single-decimal-place number with integer part zi decimal part zd.
   
   When play begins:
      let p be 1.9;
      let q be 7.5;
      let r be p multiplied correctly by q;
      let s be p divided correctly by q;
      showme r;
      showme s.

Paul.

EDIT: Damn, I have not tried this in 6G60 yet. I really should have — I will later.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Mon Jan 03, 2011 5:22 pm 
Offline

Joined: Tue Mar 18, 2008 9:04 am
Posts: 1134
If this is a problem in the new build, it sounds like bug report time.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Mon Jan 03, 2011 6:40 pm 
Offline

Joined: Wed Oct 27, 2010 6:15 pm
Posts: 344
For the second bit of code:

Code:
When play begins:
   let p be 1.9;
   let q be 7.5;
   let r be p * q;
   let s be p / q;
   showme r;
   showme s.

You have effectively said

Code:
When play begins:
   let p be 19 tenths;
   let q be 75 tenths;
   let r be p * q; [19*75=1425]
   let s be p / q; [19/75=0 (and some change, which is lost in the integer arithmetic)]
   showme r; [1425 is formatted as 142.5]
   showme s. [0 is formatted as 0.0]

so Inform has done everything correctly. Or, put another way, by writing

Code:
A single-decimal-place number times a single-decimal-place number specifies a single-decimal-place number.

you have claimed that a tenth times a tenth is a tenth.


Top
 Profile Send private message  
Reply with quote  
PostPosted: Mon Jan 03, 2011 7:17 pm 
Offline
User avatar

Joined: Mon Oct 04, 2010 11:35 am
Posts: 876
Location: Toronto
Alright, did I do wrong by setting a kind of number to multiply by itself? That is not what the Writing With Inform manual suggests, I realise, and I had a feeling that might come up. Besides, my example is sort of bending the unit system to a purpose for which it wasn't designed, and that makes it an unintuitive example.

So, let's go by the book, then. As Writing With Inform recommends, let's have a length times a length specify an area. But let's make them compound units, and see if the math comes out with anything resembling common sense reality...

Code:
The Kitchen is a room.

Length is a kind of value. 8 foot 11 specifies a length.
An area is a kind of value. 8 foot 11 inches square specifies an area.
A length times a length specifies an area.

X and Y are lengths that vary. Z is an area that varies.

X is 5 foot 4. Y is 4 foot 9.

When play begins:
   now z is x * y;
   showme x;
   showme y;
   showme z;

So now inform is telling me that when I multiply 5 foot 4 by 4 foot 9, the result is 304 feet 0 inches square. Once again, this is off by an order of magnitude, and seems to run counter to what the manual claims, which is that multiplying length units together is meant to represent an area. In order to achieve that end, Inform should have converted everything to inches, multiplied them together, and then divided everything by 12, and then by 12 again (because the result is squared) -- but it forgot to divide by 12 the second time. Just as it forgot to divide by 10 a second time when we were dealing with a base 10 system instead of the 12 inches in a foot. Seems like a simple slip-up to me. It's hard for me to imagine a situation where the current behaviour would be useful, even if by some odd technicality it proves to be correct. (I don't really understand what you did there either Emacs with the tenth times a tenth being equal to a tenth, but I'd be curious if you think this new example is also working as intended.)

Paul.

EDIT: I just checked in the latest build (6G60) — the behaviour is unchanged. I'll file a bug report using the above example (and probably a separate one, for the first bug regarding filesize calculations), assuming EmacsUser doesn't convince me yet that I've got it all wrong. 8)


Top
 Profile Send private message  
Reply with quote  
PostPosted: Mon Jan 03, 2011 7:38 pm 
Offline
User avatar

Joined: Mon Oct 04, 2010 11:35 am
Posts: 876
Location: Toronto
Hmm, I'm going to leave that last response up but I think Emacsuser is right. Because thinking about it my area specification implies that there are 12 square inches in a square foot, which is of course wrong -- there are 144 inches in a square foot. So what happens if I specify that in my area? Suddenly I get the right result (the only thing I changed was the 8 foot 11 to an 8 foot 143)...

Code:
The Kitchen is a room.

Length is a kind of value. 8 foot 11 specifies a length.
An area is a kind of value. 8 foot 143 inches square specifies an area.
A length times a length specifies an area.

Z is an area that varies.

X and Y are lengths that vary.

X is 5 foot 4. Y is 4 foot 9.

When play begins:
   now z is x * y;
   showme x;
   showme y;
   showme z;

I begin to see the light — thanks.

Maybe that first filesize bug is still worth reporting, though...

Paul.


Top
 Profile Send private message  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 6 hours [ DST ]


Who is online

Users browsing this forum: Bing [Bot] and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group