Re: Informix 5 can't handle arithmetic expressions ?
Posted in 1995
Klaus, }Is this a known bug (or feature) ? Odd though it may seem, this is the expected behaviour. All arithmetic in I4GL (p-code or c-code) is done using DECIMAL types. The intermediate results of expressions are whatever decimal type is convenient. That has led to problems in the past when the intermediate results were not properly normalized -- eg it used to be a problem if you multiplied a DEC(14, 4) by another to get DEC(28, 8), then by another to get DEC(42,12), which was truncated to DEC(32,2)), thereby losing information if the first value was 1.0010, and the second and third were both 1.0000. This has been fixed in recent versions (4.13/6.01 for sure; I think 4.12/6.00 too). The intermediate result is normalized so that for the specified calculation, the intermediate values have precision DEC(4,3), preserving all the significant digits throughout. Dissecting the code given: The variable declarations could perfectly well be local to MAIN, but this has no effect on the behaviour. All the variables are effectively INTEGER variables; the presence of the CHAR variables does not alter the displayed results apart from the presence or absence of blanks. In the comments about the displayed results, I've removed extraneous spaces as they are not material to the problem. } LET p_wiederimma = "931" [2 assignments moved] } LET semi = p_wiederimma[1,2] } DISPLAY p_wiederimma," -> ",semi The DISPLAY of "931 -> 93" is non-controversially correct. [2 moved assignments] } LET anz_hs = 14 } LET p_hs_sem_ges = "13" } LET JJi = semi - ((anz_hs - p_hs_sem_ges) / 2) } DISPLAY semi," - ((",anz_hs," - ",p_hs_sem_ges,") / 2) = ",JJi The DISPLAY of "93 - ((14 - 13) / 2) = 92" is correct. The calculation of (anz_hz - p_hs_sem_ges) yields 1; divided by 2, this yields 0.5; subtracted from semi yields 92.5; assigned to integer, this yields 92 by truncation. This is OK -- you can argue about the benefits of rounding versus truncation, but I4GL truncates. } LET diffdata = (anz_hs - p_hs_sem_ges) } DISPLAY diffdata," = ",anz_hs," - ",p_hs_sem_ges The DISPLAY of "1 = 14 - 13" is non-controversially OK. } LET JJi = semi - (diffdata / 2) } DISPLAY semi," - (",diffdata," / 2) = ",JJi The DISPLAY of "93 - (1 / 2) = 92" is OK by the same argument as before. } LET diffdata1 = diffdata / 2 } DISPLAY diffdata1," = ",diffdata," / 2" The DISPLAY of "0 = 1 / 2" is correct because the calculation yields 0.5 as a result, which is truncated to 0 on assignment. } LET JJi = semi - diffdata1 } DISPLAY semi," - ",diffdata1," = ",JJi The DISPLAY of "93 - 0 = 93" is non-controversially correct. Yours, Jonathan Leffler (johnl@informix.com) #include <disclaimer.h> PS: Rhetorical question - which version of I4GL are you using? When you ask about I4GL, the I4GL version is more important than the engine version, especially when the code to be analysed does not use a database. }From: dobrahs1@mailszrz.zrz.TU-Berlin.DE (Klaus Dobrindt) }Date: 21 Jul 1995 12:33:22 GMT }X-Informix-List-Id: <news.15623> } }I was was really surprised, when I noticed that Informix }didn't evaluate arithmetic expressions right, 1 / 2 will be 0 , if stored in }a variable, 1 / 2 will be 1 in an arithmetic expression. } }Is this a known bug (or feature) ? } }A small piece of code follows to demonstate the effect. } }Ciao Klaus } }################################################################## }GLOBALS }DEFINE } p_wiederimma CHAR(3), } semi integer, } diffdata integer, } diffdata1 integer, } anz_hs integer, } p_hs_sem_ges CHAR(2), } JJi integer }END GLOBALS } }MAIN } LET p_wiederimma = "931" } LET anz_hs = 14 } LET p_hs_sem_ges = "13" } LET semi = p_wiederimma[1,2] } DISPLAY p_wiederimma," -> ",semi } LET JJi = semi - ((anz_hs - p_hs_sem_ges) / 2) } DISPLAY semi," - ((",anz_hs," - ",p_hs_sem_ges,") / 2) = ",JJi } LET diffdata = (anz_hs - p_hs_sem_ges) } DISPLAY diffdata," = ",anz_hs," - ",p_hs_sem_ges } LET JJi = semi - (diffdata / 2) } DISPLAY semi," - (",diffdata," / 2) = ",JJi } LET diffdata1 = diffdata / 2 } DISPLAY diffdata1," = ",diffdata," / 2" } LET JJi = semi - diffdata1 } DISPLAY semi," - ",diffdata1," = ",JJi } LET semi = JJi }END MAIN } }produces the following output: } }931 -> 93 } 93 - (( 14 - 13) / 2) = 92 } 1 = 14 - 13 } 93 - ( 1 / 2) = 92 } 0 = 1 / 2 } 93 - 0 = 93 } }What a weird arithmetic expression handling is this? } }The division operator "/" ignores any reminder on division of two }integers (3-13U) } }I'm using INFORMIX-OnLine Version 5.01.UD3 } }----------------------------------------------------------------------------- }| Klaus Dobrindt dobrahs1@mailszrz.zrz.tu-berlin.de | }| Turmstr. 44 tel.: (priv) +49 30 396 72 44 | }| 10551 Berlin (off) 3185-2737 | }| Germany fax : (off) -2781 | }-----------------------------------------------------------------------------