htfloats.hss 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. [Main]
  2. Title=Using Floating Point Arithmetic
  3. [Top]
  4. If you have used earlier releases of TIGCC (prior to 0.9), you probably know that the use of floating
  5. point values and functions was possible, but only using some very awkward syntax, which caused a lot of
  6. headaches and nightmares. The TIGCC team (mostly
  7. <A HREF="mailto:SebastianR@gmx.de">Sebastian Reichelt</A> and
  8. <A HREF="mailto:zjuric@utic.net.ba">Zeljko Juric</A>) spent a lot
  9. of time and effort implementing native (ANSI) floats in TIGCC. And the results are now available:
  10. you can use regular floating point numbers and values now, as in all regular C compilers! This means
  11. that:
  12. <UL>
  13. <LI>
  14. You can now use the standard ANSI types <CODE>float</CODE>, <CODE>double</CODE> and
  15. <CODE>long&nbsp;double</CODE> without any trouble (in fact, these three types are the same,
  16. there is no difference between them). The old-style type <A HREF="$$LINK(timath.h/ti_float)">ti_float</A>
  17. still exists due to compatibility reasons, but now it is the same as <CODE>float</CODE>.
  18. </LI>
  19. </UL>
  20. <UL>
  21. <LI>
  22. You can now use "standard" floating point constants (like 2.854). So, the following is now valid:
  23. <PRE>float a, b, c;
  24. a = 2.854;
  25. b = 7;
  26. c = 1.5e-7;
  27. </PRE>
  28. In other words, no more ugly <A HREF="$$LINK(timath.h/M_FLT)">FLT</A> and
  29. <A HREF="$$LINK(timath.h/M_FEXP)">FEXP</A> macros! They still exist due to compatibility reasons,
  30. but their usage is very deprecated now.
  31. </LI>
  32. </UL>
  33. <UL>
  34. <LI>
  35. You can now use standard arithmetic ('+', '-', '*', '/) and comparison ('&lt;', '&gt;',
  36. '&lt;=', '&gt;=', '==' and '!=') operators with floating point values. There is no need any more
  37. for the use of awkward functions like <A HREF="$$LINK(timath.h/fadd)">fadd</A>,
  38. <A HREF="$$LINK(timath.h/fcmp)">fcmp</A> etc. So statements like these are now accepted:
  39. <PRE>p = (q + 3.15) / (q - r);
  40. x1 = (-b + sqrt (b * b - 4 * a * c)) / (2 * a);
  41. if (p &lt; 3.0) q += 1e-3;
  42. </PRE>
  43. This feature is probably the best present for TIGCC users...
  44. </LI>
  45. </UL>
  46. <UL>
  47. <LI>
  48. You can use all floating point functions (like <A HREF="$$LINK(timath.h/sqrt)">sqrt</A>,
  49. <A HREF="$$LINK(timath.h/sin)">sin</A> etc.) as usual. In this release, a standard ANSI
  50. math library <A HREF="$$LINK(math.h/)">math.h</A> is implemented, which contains nearly all
  51. functions proposed by ANSI C, with some extensions. The old
  52. <A HREF="$$LINK(timath.h/)">timath.h</A> library file still exists due to compatibility reasons,
  53. and it contains more functions than <A HREF="$$LINK(math.h/)">math.h</A>, because it contains
  54. some functions for making compatibility with older programs, and some functions which are
  55. internally related to the TIOS. Anyway, you can do calculations like these:
  56. <PRE>a = sin (b);
  57. b = exp (1);
  58. c = log (3.19);
  59. a = sqrt (b + c) * sinh (a / 2.);
  60. </PRE>
  61. As you can see from the second example, automatic promotion from integer constants to
  62. the floating point is also implemented.</LI>
  63. </UL>
  64. <UL>
  65. <LI>
  66. Integer types are now automatically promoted to floating point values when necessary, as
  67. proposed in ANSI C. This means that the following constructions are valid, assuming that
  68. <CODE>'n'</CODE> is a variable of integer (short, long, signed, unsigned) type:
  69. <PRE>a = n;
  70. b = sqrt (n);
  71. c = b + n;
  72. </PRE>
  73. You can also explicitely cast an integer value to a floating point one:
  74. <PRE>a = (float)n;
  75. </PRE>
  76. The function <A HREF="$$LINK(timath.h/flt)">flt</A> which performs the promotion explicitely
  77. still exists, due to compatibility reasons.
  78. </LI>
  79. </UL>
  80. <UL>
  81. <LI>
  82. Floating point types are automatically truncated to integers when the program
  83. expects an integer value (for example, when a floating point variable is assigned to an integer
  84. variable), as proposed in ANSI C. This means that you can write
  85. <PRE>n = a;
  86. </PRE>
  87. where <CODE>'n'</CODE> is an integer, and <CODE>'a'</CODE> is a float, although it is better
  88. to express your wish more explicitely using type cast as
  89. <PRE>n = (int)a;</PRE>
  90. The function <A HREF="$$LINK(timath.h/trunc)">trunc</A> which performs the
  91. truncation explicitely still exists due to compatibility reasons.
  92. </LI>
  93. </UL>
  94. <UL>
  95. <LI>
  96. You can use <A HREF="$$LINK(stdio.h/printf)">printf</A> and similar
  97. functions to print floating point values, using the format specifiers <CODE>%f</CODE>,
  98. <CODE>%e</CODE> and <CODE>%g</CODE>, as defined in ANSI C. So, the following is
  99. completely legal:
  100. <PRE>printf ("sin(%f)=%f", a, sin(a));
  101. printf ("%f", 3.14);</PRE>
  102. Note that the second statement was not valid prior to release 0.9 of TIGCC!
  103. </LI>
  104. </UL>
  105. <UL>
  106. <LI>
  107. To accept a floating point value from the keyboard, first accept it as a string (using
  108. <A HREF="$$LINK(stdio.h/gets)">gets</A>, some user-written input routine, or
  109. functions from <A HREF="$$LINK(dialogs.h/)">dialogs.h</A>), then
  110. convert the string to a floating point value using the <A HREF="$$LINK(timath.h/atof)">atof</A>
  111. (ascii-to-float) function. To get a floating point argument passed from TI-Basic to the
  112. program, use the <A HREF="$$LINK(args.h/GetFloatArg)">GetFloatArg</A> function.
  113. </LI>
  114. </UL>
  115. As you can see, the usage of floats with TIGCC is now essentially the same as in all other C
  116. compilers. See the description of the <A HREF="$$LINK(math.h/)">math.h</A> and
  117. <A HREF="$$LINK(timath.h/)">timath.h</A> header files for more info. However, floating point
  118. support in TIGCC is not perfect yet. That's why there are still some limitations
  119. in the use of floating point values (fortunately, they are not serious):
  120. <UL>
  121. <LI>
  122. The promotion of double long integers (<A HREF="$$INFOLINK(gnuexts/SEC72)">long long</A> types) to
  123. floating point values, and truncation of floating point values to longlongs are not implemented
  124. yet. If you try to do this (which is not very likely), you will get an "undefined reference"
  125. error during the linking stage.
  126. </LI>
  127. </UL>
  128. As an example of usage of floating point values and functions, the program given below
  129. (called "Float Test") reads coefficients of a quadratic equation from the keyboard, then
  130. calculates and displays the solutions of the equation (including complex ones):
  131. $$EXAMPLE(Float Test.c)
  132. See the description of the included header files for more info about the functions used.
  133. <BR><BR>
  134. As already mentioned above, the new floating point support is implemented without
  135. losing compatibility with programs written with releases of TIGCC before 0.9
  136. (more precise, the degree of compatibility is about 95%; read further to see possible
  137. reasons of incompatibility). So, the quadratic equation solver given below, which
  138. is written using old methods (prior to TIGCC 0.9), will still work with a new compiler.
  139. Compare this (old-style) code with the previous (new-style) one to see how much clearer
  140. the new-style code is...
  141. <PRE>#define SAVE_SCREEN
  142. #include &lt;stdio.h&gt;
  143. #include &lt;timath.h&gt;
  144. #include &lt;string.h&gt;
  145. #include &lt;kbd.h&gt;
  146. int _ti89, _ti92plus;
  147. void _main (void)
  148. {
  149. ti_float a, b, c, d;
  150. char buffer[200];
  151. clrscr ();
  152. puts ("a=");
  153. a = atof (gets (buffer));
  154. puts ("b=");
  155. b = atof (gets (buffer));
  156. puts ("c=");
  157. c = atof (gets (buffer));
  158. if (is_nan (a) || is_nan (b) || is_nan (c)) return;
  159. d = fsub (fmul (b, b), fmul (FLT (4), fmul (a, c)));
  160. if (fcmp (d, ZERO) &gt;= 0)
  161. {
  162. ti_float x1, x2;
  163. x1 = fdiv (fadd (fneg (b), sqrt (d)), fadd (a, a));
  164. x2 = fdiv (fsub (fneg (b), sqrt (d)), fadd (a, a));
  165. printf ("\nx1=%f\nx2=%f", x1, x2);
  166. }
  167. else
  168. {
  169. ti_float re, im;
  170. re = fdiv (fneg (b), fadd (a,a));
  171. im = fabs (fdiv (sqrt (fneg (d)), fadd(a, a)));
  172. printf ("\nx1=%f-%f*i\nx2=%f+%f*i", re, im, re, im);
  173. }
  174. ngetchx();
  175. }
  176. </PRE>
  177. The possible reasons which may cause incompatibility (very unlikely) with programs written
  178. with older versions of TIGCC (prior to 0.9) are:
  179. <UL>
  180. <LI>
  181. The types <A HREF="$$LINK(timath.h/ti_float)">ti_float</A> and <A HREF="$$LINK(timath.h/bcd)">bcd</A>
  182. are not the same any more.
  183. <CODE>ti_float</CODE> is now equal to ANSI type <CODE>float</CODE>, but
  184. <CODE>bcd</CODE> is still a structure. If your program uses the
  185. <CODE>bcd</CODE> type (not very likely), you should probably change it to
  186. <CODE>float</CODE> to make the program work, because functions which expect a
  187. <CODE>float</CODE> type will not accept a structured type. Two macros called
  188. <A HREF="$$LINK(timath.h/float_to_bcd)">float_to_bcd</A> and
  189. <A HREF="$$LINK(timath.h/bcd_to_float)">bcd_to_float</A> have been introduced to provide more general
  190. conversion if necessary.
  191. </LI>
  192. </UL>
  193. <UL>
  194. <LI>
  195. Functions <A HREF="$$LINK(timath.h/fadd)">fadd</A>, <A HREF="$$LINK(timath.h/fsub)">fsub</A>,
  196. <A HREF="$$LINK(timath.h/fmul)">fmul</A>, <A HREF="$$LINK(timath.h/fdiv)">fdiv</A>,
  197. <A HREF="$$LINK(timath.h/fneg)">fneg</A>, <A HREF="$$LINK(timath.h/fcmp)">fcmp</A>,
  198. <A HREF="$$LINK(timath.h/flt)">flt</A> and <A HREF="$$LINK(timath.h/trunc)">trunc</A> are not
  199. absolutely equal to functions
  200. <A HREF="$$LINK(timath.h/bcdadd)">bcdadd</A>, <A HREF="$$LINK(timath.h/bcdsub)">bcdsub</A>,
  201. <A HREF="$$LINK(timath.h/bcdmul)">bcdmul</A>, <A HREF="$$LINK(timath.h/bcddiv)">bcddiv</A>,
  202. <A HREF="$$LINK(timath.h/bcdneg)">bcdneg</A>, <A HREF="$$LINK(timath.h/bcdcmp)">bcdcmp</A>,
  203. <A HREF="$$LINK(timath.h/bcdbcd)">bcdbcd</A> and <A HREF="$$LINK(timath.h/bcdlong)">bcdlong</A> any more.
  204. The first group of functions now works with the ordinary <CODE>float</CODE> type (and they
  205. will continue to work with <A HREF="$$LINK(timath.h/ti_float)">ti_float</A>), but the second
  206. group now only works with <A HREF="$$LINK(timath.h/bcd)">bcd</A> structures. So, if you used
  207. <CODE>bcdadd</CODE> etc. in your program (not very likely), you should
  208. probably change it to <CODE>fadd</CODE> etc. to make the program work.
  209. </LI>
  210. </UL>
  211. <UL>
  212. <LI>
  213. Suppose that your old program uses the <A HREF="$$LINK(timath.h/ti_float)">ti_float</A> type with
  214. direct access to its internal fields (not very likely), like in the following example:
  215. <PRE>ti_float a;
  216. a.exponent = 0x4003;
  217. a.mantissa = 0x3284300000000000;
  218. </PRE>
  219. Then the program will not work with the new compiler, because <CODE>ti_float</CODE> is not a
  220. structure any more. Using a new macro <A HREF="$$LINK(timath.h/bcd_var)">bcd_var</A> you can easily
  221. get your program to work. All you need to do is to re-express the above statements as
  222. <PRE>ti_float a;
  223. bcd_var(a).exponent = 0x4003;
  224. bcd_var(a).mantissa = 0x3284300000000000;
  225. </PRE>
  226. Note, however, that the <A HREF="$$LINK(timath.h/bcd)">bcd</A> type is still a structure.
  227. </LI>
  228. </UL>