home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / assembler / thesource / volume4 / source / vectors / fixedpoint.lha / FixedPointMath.txt
Encoding:
Text File  |  1993-03-06  |  30.7 KB  |  798 lines

  1. Hi!
  2.  
  3. Here's all the messages concerning integer math that I received (via mail or 
  4. News) and saved. This file is just a simple concatenation of all the messages,
  5. 'cause I haven't had time to write any summaries or anything... Anyway, I hope
  6. this helps you, it certainly clarified the basic concepts to me! O:)
  7.  
  8. -MiS-
  9. /*                Mika Saastamoinen                 */
  10. /*            (mikasaas@polaris.utu.fi/msaastamoine@finabo.abo.fi)           */
  11. /*     Student at Turku School of Economics - Information Systems Science    */
  12. #include <stddisclaimer.h>
  13. #define AMIGA_In_an_insane_world_it_is_the_sanest_choice TRUE
  14.  
  15. ----------------...
  16.  
  17. In article <1993Feb12.110623.6317@abo.fi> MSAASTAMOINE@FINABO.ABO.FI (Mika Saastamoinen Tkkk) writes:
  18. >Hi ya'all!
  19. >
  20. >I was wondering if someone could explain to me the basic principles of integer
  21. >math. Specifically, I'm thinking of the kind of math one uses in 3D (vector)
  22. >graphics programming. Since I'm not so awfully hot on math I thought I'd ask 
  23. >you Gurus about this! O:)
  24.  
  25. I wouldn't consider myself a guru at it but I should be able to help you.  I
  26. used an integer scheme on the 6809 for Currilian Cruiser (a game I wrote
  27. and tried to sell back in high school)
  28.  
  29. >Let's say I'm thinking of the floating point number '1.234567890': How do I
  30. >convert that to integer without losing accuracy too much 
  31.  
  32. First let me describe the data structure for what I called fixed point numbers.
  33. For this example I am going to assume 16bit integers however this is scalable
  34. up or down.
  35.  
  36. your data would look like this
  37. (16bit Integer)(16bit Fraction) where the fraction is an integer count of
  38. 65536ths.  I hope this is clear.  Eg (1234)(32768) is 1234.5
  39.  
  40. Now to answer the question, the representation of the above number 1.234567890
  41. would be (1)(15373) and the translation from fixed point back to decmal is:
  42. 1.23457336, this shows your error factor for this number using a 16 bit
  43. fraction.
  44.  
  45. How do you convert from/to this format?
  46. To convert a number like this 12345.6789
  47. take the integer part and store it in the first 16 bits (12345)
  48. take the fractional part and multiply it by 65536, .6789*65536=(44492)
  49.  
  50. To convert a fixed point number like (12345)(44492) to decimal:
  51. The integer part is in the first 16bit 12345.
  52. The fractional part is obtained by dividing 44492 into 65536: .67889409
  53. Add the two part 12345.+.67889409 = 12345.67889409
  54.  
  55. This system may appear slower at this point, no it's not. Conversions can
  56. be be done at compile time or done with a calculator and entered manually
  57. if needed.  Youy speedup is obtained in the math.  Also the fractional part
  58. may be ignored for some applications.
  59.  
  60. >                                                         and how would I go
  61. >about using that integer number in various calculation (mult,div,add,subs) 
  62. >with (maybe) one or more of the same kind of integer numbers? 
  63. The integer numbers are transformed into fixed point numbers by using using
  64. the integer and clearing another 16bit value (hopefully behind the 16bit
  65. integer).  Now you simply preform the integer 32bit operations.  If your
  66. archetecture doesn't support 32 bit operations use the add with carry
  67. schemes.  Note an integer over/underflow/zero have the same meanings
  68. co compares and condition code side affects can be used for your favorite
  69. branching instructions.
  70.  
  71. >
  72. >Conversion: Do I multiply the float number by something or do I use 2 variables
  73. >(one for the integer part ('1') & one for the fractions ('234567890')) to 
  74. >describe it or what?
  75.  
  76. Sort of, just remember to do the divide/multiply by the base(in my examples it
  77. is 2^16 because I am have a 16bit example) to get your fractions.
  78.  
  79.  
  80. >Calculation: What if I had this kind of formula: 'y = A*x*x + B*x + C', where
  81. >A,B and C are 'converted' integers and x and y 'normal' integers. What do I
  82. >have to do get a 'correct' answer out of that formula? If I've multiplied the
  83. >floats, do I divide the result of that formula by the number I multiplied the
  84. >floats to begin with or if I use that 2-variable-approach... well, I don't
  85. >know what I'd do then!
  86. It's simple:
  87.  
  88. (y)(Don'tCare)=(A)(0)*(xInt)(xFra)*(xInt)(xFra)+(B)(0)
  89.                *(xInt)(xFra)+(C)(0)
  90.  
  91. if you want to round off instead of truncating to minimize error, do this:
  92.  
  93. (y)(Don'tCare)=(A)(0)*(xInt)(xFra)*(xInt)(xFra)+(B)(0)
  94.                *(xInt)(xFra)+(C)(0)+(0)(32768)
  95.  
  96. So this operation on say a MC68000 would take 5 or 6 instructions of
  97. in-line code, no subroutine/function calls, lightning fast.
  98.  
  99.  
  100. >I've already learnt that using lookup-tables for sin and cos values speeds
  101. >the (3D vector-) thing up somewhat, but those values are still in floating 
  102. >point. Now I'd like to know 'How-to-convert' and 'How-to-use-in-calculation'...
  103. Use the method I described to convert decmimal numbers to fixed point numbers.
  104. Then use the fixed point numbers in the table.  Note since you are dealing
  105. with sin/cos all of your integer parts of the fixed numbers will be 0.  If
  106. space is needed the table can be compressed.  Since sin and cos share datasets
  107. you can also save space by running the sin table from 0 to 250 degrees
  108. to get cos X values just use sin X+90
  109. >                                                                              
  110. >Say, does it make much difference (in performance) whether you use integer or 
  111. >floating point math in any case?
  112. That will change from machine to machine.
  113. >
  114. >BTW, I'm using C, so if you have any bits of integer math code handy in that
  115. >language, could you please send me some? 
  116. >
  117. >Thanx for... well, whatever you can tell me! ;)
  118. >
  119. >/*                Mika Saastamoinen                 */
  120. >/*            (mikasaas@polaris.utu.fi/msaastamoine@finabo.abo.fi)           */
  121. >/*     Student at Turku School of Economics - Information Systems Science    */
  122. >#include <stddisclaimer.h>
  123. >#define AMIGA_In_an_insane_world_it_is_the_sanest_choice TRUE
  124. >
  125.  
  126.  
  127. If something isn't clear I'll try to clarify it for you.  I don't have
  128. much time to proof read this and make is sound better, I cannot slip
  129. my schedule.  Plus not many people are reading it since it has nothing
  130. to do with IBM compatables super VGA graphics or any of that trash. ;)
  131. It is such a pain trying to read a newsgroup with so much IBM crap in
  132. it all the time, oh well enough complaining.
  133.  
  134. - Brent LaVelle
  135. lavelle@convex.com
  136.  
  137. ----------------....
  138.  
  139. In article <1993Feb12.231906.723@news.eng.convex.com> lavelle@convex.com (Brent LaVelle) writes:
  140. >In article <1993Feb12.110623.6317@abo.fi> MSAASTAMOINE@FINABO.ABO.FI (Mika Saastamoinen Tkkk) writes:
  141. >>Hi ya'all!
  142. >>
  143. >>I was wondering if someone could explain to me the basic principles of integer
  144. >>math. Specifically, I'm thinking of the kind of math one uses in 3D (vector)
  145. >>graphics programming. Since I'm not so awfully hot on math I thought I'd ask 
  146. >>you Gurus about this! O:)
  147. >
  148. >I wouldn't consider myself a guru at it but I should be able to help you.  I
  149. >used an integer scheme on the 6809 for Currilian Cruiser (a game I wrote
  150. >and tried to sell back in high school)
  151. [long discussion deleted...]
  152.  
  153. I found that discussion to be a little unclear, but what he seemed to be
  154. saying (and what I've done), is that you just take your floating point
  155. number, and multiply it by some constant to get rid of the fractional
  156. part.
  157.  
  158. For example lets take the number 1234.5678 what we might do is multiply
  159. it by 10000 to get the integer number 12345678, and then we can do 
  160. calculations with this integer.  Adds and subtracts work normally,
  161. you don't have to do anything special.  If you multiply two numbers,
  162. you have to divide the result by your constant to get the true
  163. answer like so:
  164.     say we got 1.1 and 2.5
  165.     converting them we get 11000 and 25000
  166.     11000*25000/10000 = 27500
  167.  
  168. If you convert 27500 back to normal numbers you get 2.75 which is equal
  169. to 1.1 * 2.5.  Dividing is the same way, accept that you need to
  170. multiply the first number by your constant before doing the division.
  171. Oh yeah, make sure that when you are multiplying your do the
  172. consant division last otherwise you'll lose accuracy.
  173.  
  174. Typically you should use some power of two as your constant, this allows
  175. fast conversions just by doing shifts (If you want to find 4*x, you
  176. just shift x left twice)  What constant should you use? The trade off 
  177. is that bigger constants give you more accuracy but a smaller range.
  178. I think he mentioned 65536 (2^16), I've found that 256 (2^8) is
  179. adequate.
  180.  
  181. Well, hopefully that's somewhat clear...
  182.  
  183.                 -Mike
  184. --------------------....
  185.  
  186. In article <1993Feb12.110623.6317@abo.fi> MSAASTAMOINE@FINABO.ABO.FI (Mika Saastamoinen Tkkk) writes:
  187.  
  188.    I was wondering if someone could explain to me the basic principles
  189.    of integer math. Specifically, I'm thinking of the kind of math one
  190.    uses in 3D (vector) graphics programming. Since I'm not so awfully
  191.    hot on math I thought I'd ask you Gurus about this! O:)
  192.  
  193.    Let's say I'm thinking of the floating point number '1.234567890':
  194.    How do I convert that to integer without losing accuracy too much
  195.    and how would I go about using that integer number in various
  196.    calculation (mult,div,add,subs) with (maybe) one or more of the
  197.    same kind of integer numbers?
  198.  
  199. The following is an extract from some technical documentation I
  200. started writing for our PC game, Netspace, several months ago.  Note
  201. that I've set the follow-up to just rec.games.programmer.  I apologize
  202. for being platform specific, but I assume the general principles
  203. should be easily adaptable to the Amiga as well.
  204.  
  205. **** included text
  206.  
  207. Netspace uses a 32-bit fixed-point math library.  The basic data type
  208. in the library is a scalar stored as a 32-bit integer.  A vector
  209. ("vect") is an array of three scalars and a viewing coordinate system,
  210. a basis, is an array of three orthonormal vect's.
  211.  
  212. Scalars are 32-bit fixed-point numbers.  They use 30 bits for the
  213. fractional part and two bits for the whole number giving a range for a
  214. scalar X from -2 <= X < 2.  Scalars are treated in C as long ints.
  215. They can be added, subtracted, assigned and compared the same as longs.
  216. Multiplying two scalars, however, creates a 64-bit result that must be
  217. right-shifted by 30 bits to store back into a 32-bit long.
  218.  
  219.  
  220. X, Y, Z are fixed-point; x, y, z are floating-point:
  221.  
  222.         X == x*2^30
  223.  
  224.         (x + y)*2^30 == (x*2^30) + (y*2^30)
  225.         X + Y <- X + Y
  226.  
  227.         (x * y)*2^30 == (x*2^30) * (y*2^30) / 2^30
  228.         X * Y <- X * Y / 2^30
  229.  
  230.         (x / y)*2^30 == (x*2^30) * 2^30 / (y*2^30)
  231.         X / Y <- X * 2^30 / Y
  232.  
  233.         sqrt(x)*2^30 == sqrt((x*2^30) * 2^30)
  234.         sqrt(X) <- sqrt(X * 2^30)
  235.  
  236.         mag(v = (x*2^30, y*2^30, z*2^30)) ==
  237.             sqrt(x*2^30 * x*2^30 + y*2^30 * y*2^30 + z*2^30 * z*2^30)
  238.         mag(V = (X, Y, Z)) <- sqrt(X * X + Y * Y + Z * Z))
  239.  
  240.  
  241. The math library began with a few basic scalar operations, such as
  242. multiply, divide, and square root.  We later added a 32-bit shift
  243. function when we realized that our 16-bit C compiler was performing
  244. them as a loop of single bit shift pairs (shift the high word one bit
  245. right, shift the low word with carry-in.)
  246.  
  247. Under MS-DOS, the stack is only 16 bits wide.  This means that passing
  248. a single 32-bit value takes two push operations, one for the high two
  249. bytes and another for the low.  As a result, calling several 32-bit
  250. math routines in succession can be very slow.  We have avoided this by
  251. converting just about every occurance of two or more consecutive math
  252. library calls into a single assembly routine.  We now have a routine,
  253. for instance, which multiplies a vector by a scalar, adds it to a
  254. second vector and stores the result in a third.  Converting
  255. complicated arithmetic expressions to assembly gave a marked
  256. improvement in speed.
  257.  
  258. **** end inclusion
  259.  
  260.    Conversion: Do I multiply the float number by something or do I use
  261.    2 variables (one for the integer part ('1') & one for the fractions
  262.    ('234567890')) to describe it or what?
  263.  
  264. Store it in a single int (or long) and simply pretend you know where
  265. the radix point is (2.30 in my example above.)  The multiply opcode on
  266. the 386 generates a 64-bit result which I can easily right-shift to
  267. get the radix point back in the correct place.  Think back to how you
  268. placed the decimal point in long division back in grade school.
  269.  
  270.    Say, does it make much difference (in performance) whether you use
  271.    integer or floating point math in any case?
  272.  
  273. After some recent e-mail conversations I've had, if you were on a 486
  274. with its built-in math coprocessor, I would say save yourself the
  275. trouble of dealing with the integer overflows and stick with
  276. floating-point.  I have no familiarity with Amigas, however, so your
  277. mileage may vary.  We achieved and extremely noticeable speed up with
  278. fixed-point on a 386 which also had a math coprocessor.  Try it both
  279. ways and find out.
  280.  
  281.    BTW, I'm using C, so if you have any bits of integer math code
  282.    handy in that language, could you please send me some?
  283.  
  284. Sorry, all my math code is in assembly so that it can deal directly
  285. with the registers for the extended multiply results and subsequent
  286. shifts.
  287.  
  288.    Thanx for... well, whatever you can tell me! ;)
  289.  
  290. My pleasure.
  291.  
  292.    /*            Mika Saastamoinen                 */
  293.    /*    (mikasaas@polaris.utu.fi/msaastamoine@finabo.abo.fi)   */
  294.    /* Student at Turku School of Economics - Information Systems Science */
  295.    #include <stddisclaimer.h>
  296.    #define AMIGA_In_an_insane_world_it_is_the_sanest_choice TRUE
  297.            ^^^^^                              ^^^^^^
  298. Hee hee.  I'm sitting in a room with four rs6000's, four HP 700's,
  299. four DECstation 2000's and six Sparc2's.  I think I'd rather be insane
  300. that suffer on an Amiga.  (Sorry, I just liked the contrast.)
  301.  
  302.  
  303.                     - Steven Dollins
  304. Brown Computer Graphics Group        scd@cs.brown.edu
  305. --
  306. He was spoiled and had a trust fund that wouldn't fit in a 32-bit int.
  307.  
  308. --------------...
  309.  
  310. By Integer math I take it you mean Fixed Point.
  311.  
  312. In that case, it's easy to do. You define a long value (4 bytes),
  313. and use the top two as integer, and the bottom two as fraction.
  314.  
  315. This gives approx. 4 decimal places accuracy, but can be much
  316. faster than floating point.
  317.  
  318. When doing math, you typically can only do a FXP by INT function:
  319.  
  320. 0x45555 * 5
  321.  
  322. This is the same as 4.333 * 5, and the answer yielded is:
  323.  
  324. 0x15AAA9, or 21.6670, where 4.333*5 is 21.665, so it's fairly accurate.
  325.  
  326. You convert from floating point to FXP (fixed point) by doing a simple
  327. multiply:
  328.  
  329. fxpvar = floatvar * 65536
  330.  
  331. and to convert back, it's
  332.  
  333. floatvar = fxpvar/65536
  334.  
  335. Also, when extracting the integer, doing a:
  336.  
  337. myint = fxp>>16
  338.  
  339. yeilds a SWAP instruction (using the SAS/C compiler) which is the most
  340. efficient way to get the integer value.
  341.  
  342. I hope this helps.
  343.  
  344. -----------...
  345.  
  346. Right, the way I solve this problem is roughly like this:
  347.  
  348. You want to hold the number 1.234567
  349. What I do is to store every number as fixed point ie.  every number stored is
  350. 1000 times bigger than the real number.
  351.  
  352. ie. I store 1234 (and lose the rest)
  353.  
  354. To add/subtract just add the numbers together
  355.  
  356. To multiply: multiply and then divide the result bu 1000.
  357.  
  358. To divide: multiply one of them by 1000 then divide it by the other one.
  359.  
  360. Nb.  be careful or you`ll lose precision when you multiply
  361.  
  362. ie.  Multiplying by 1234 rapidly becomes the same as multiplying by 1000.
  363.  
  364.  
  365.  
  366. Or bit-wise:  I always store my vector stuff in 16 bit words (for speed)
  367.  
  368. the upper 9 bits hold the position of point on screen, the lower 7 hold spare s
  369. pace (ie. for the decimals (binerials?)- for accuracy).  Multiplying and dividi
  370. ng is rather like I suggested for base 10, but more complicated.....
  371.  
  372.  
  373. Have Fun with life and don`t hesitate to contact me if you have further problem
  374. s...
  375.  
  376.  
  377.  
  378. Sincere regards
  379.  
  380. Ollie
  381.  
  382.  
  383. > ----------------------------Original text follows----------------------------
  384. >
  385. > Hi ya'all!
  386. >
  387. > I was wondering if someone could explain to me the basic principles of integer
  388. > math. Specifically, I'm thinking of the kind of math one uses in 3D (vector)
  389. > graphics programming. Since I'm not so awfully hot on math I thought I'd ask
  390. > you Gurus about this! O:)
  391. >
  392. > Let's say I'm thinking of the floating point number '1.234567890': How do I
  393. > convert that to integer without losing accuracy too much and how would I go
  394. > about using that integer number in various calculation (mult,div,add,subs)
  395. > with (maybe) one or more of the same kind of integer numbers?
  396. >
  397. > Conversion: Do I multiply the float number by something or do I use 2
  398. variables
  399. > (one for the integer part ('1') & one for the fractions ('234567890')) to
  400. > describe it or what?
  401. >
  402. > Calculation: What if I had this kind of formula: 'y = A*x*x + B*x + C', where
  403. > A,B and C are 'converted' integers and x and y 'normal' integers. What do I
  404. > have to do get a 'correct' answer out of that formula? If I've multiplied the
  405. > floats, do I divide the result of that formula by the number I multiplied the
  406. > floats to begin with or if I use that 2-variable-approach... well, I don't
  407. > know what I'd do then!
  408. >
  409. > I've already learnt that using lookup-tables for sin and cos values speeds
  410. > the (3D vector-) thing up somewhat, but those values are still in floating
  411. > point. Now I'd like to know 'How-to-convert' and
  412. 'How-to-use-in-calculation'...
  413. >
  414. > Say, does it make much difference (in performance) whether you use integer or
  415. > floating point math in any case?
  416. >
  417. > BTW, I'm using C, so if you have any bits of integer math code handy in that
  418. > language, could you please send me some?
  419. >
  420. > Thanx for... well, whatever you can tell me! ;)
  421. >
  422. > /*                Mika Saastamoinen                 */
  423. > /*            (mikasaas@polaris.utu.fi/msaastamoine@finabo.abo.fi)
  424. */
  425. > /*     Student at Turku School of Economics - Information Systems Science
  426. */
  427. > #include <stddisclaimer.h>
  428. > #define AMIGA_In_an_insane_world_it_is_the_sanest_choice TRUE
  429. >
  430.  
  431. -----------------...
  432.  
  433. Well. I'm not a guru in integer math either, but I did calculations of some
  434. fractals which I was quite happy with. What I did was to have some bits in
  435. the decimal part and some bits in the integer part.
  436. example:    1010,0101 (4 bits integer and 4 bits decimal) 
  437.  
  438. Adding and subing is now done in the axactly same way as if it was just an
  439. ordinary integer number.
  440.     add.l    d0,d1
  441. or    sub.l    d0,d1
  442.  
  443. Muling is done by muling the two numbers and shifting the result n bits to
  444. the right. ( n is the number of bits in the decimal part. In our example
  445. it is 4.)
  446.     muls    d0,d1
  447.     lsr.l    #n,d1
  448. Why does it work this way? Well.. think of writing the number in an integer
  449. and a decimal part, but with an extra factor. Example:  N = I*(2^n)*D , where
  450. (2^n) is the extra factor which actually is the number you have to mutiply an
  451. integer with to get the same integer in your system. (n is the number of bits
  452. for the decimals), I is the integer part and D is the decimal part.  When you
  453. multiply N1 and N2 you get :  I1*I1*(2^n)*(2^n)*D1*d2 , but the number should
  454. have just (2^n) as a factor, therefore we divide the result by (2^n). This is
  455. the same as shifting the result n bits to the right.
  456. Does this clear it up? I hope so, but I think not.
  457.  
  458.  
  459. Dividing (q/r) is done by shifting q n bits to the left and dividing q by r.
  460.     lsl.l    #n,d0
  461.     divs    d1,d0
  462.  
  463. (Hmm... actually I've never tried dividing two integers, but I think this should
  464. work.)
  465.  
  466. Well, I don't know if it was this you were looking for, and I don't know if this
  467. is the best way of doing it, but it sure helpedalot when I made it in assembly.
  468. I hope that it can be of some help.
  469.  
  470. -- 
  471.  /---------------------------------------------------------------------------\ 
  472. (  10 rem *** Nice program! ***             |   Letters: abcdefghijklmnopq    )
  473.  ) 20 print"Espen Skoglund is my name. ";   |            rstuwxyzABCDEFGHI   (
  474. (  30 goto 20                               |            JKLMNOPQRSTUVWXYZ    )
  475.  \---------------------------------------------------------------------------/
  476.  
  477. -----------------...
  478.  
  479. In article <1993Feb12.110623.6317@abo.fi> you write:
  480. > Hi ya'all!
  481. > I was wondering if someone could explain to me the basic principles of integer
  482. > math. Specifically, I'm thinking of the kind of math one uses in 3D (vector)
  483. > graphics programming. Since I'm not so awfully hot on math I thought I'd ask 
  484. > you Gurus about this! O:)
  485. > Let's say I'm thinking of the floating point number '1.234567890': How do I
  486. > convert that to integer without losing accuracy too much and how would I go
  487. > about using that integer number in various calculation (mult,div,add,subs) 
  488. > with (maybe) one or more of the same kind of integer numbers? 
  489. > Conversion: Do I multiply the float number by something or do I use 2 variables
  490. > (one for the integer part ('1') & one for the fractions ('234567890')) to 
  491. > describe it or what?
  492.     The usual approach is to multiply with something. But I suppose
  493.     this is up to you. By using two variables you will ofcourse get 
  494.     a much more accurate representation.
  495.  
  496.  
  497. > Calculation: What if I had this kind of formula: 'y = A*x*x + B*x + C', where
  498. > A,B and C are 'converted' integers and x and y 'normal' integers. What do I
  499. > have to do get a 'correct' answer out of that formula? If I've multiplied the
  500. > floats, do I divide the result of that formula by the number I multiplied the
  501. > floats to begin with or if I use that 2-variable-approach... well, I don't
  502. > know what I'd do then!
  503.  
  504.     Well, the first thing I would do was rewrite the formula....=)
  505.  
  506.     y = x(A*x+B)+C
  507.  
  508.     And to get the right answer you divide by the factor you used above.
  509.     With the two variable approach, this gets more complicated as
  510.     you get more multiplications and have to take into accont the
  511.     state of C(arry)-Flag;
  512.  
  513. > I've already learnt that using lookup-tables for sin and cos values speeds
  514. > the (3D vector-) thing up somewhat, but those values are still in floating 
  515. > point. Now I'd like to know 'How-to-convert' and 'How-to-use-in-calculation'...
  516.  
  517.  
  518.     HOW TO CONVERT:
  519.  
  520. #define        PI    3.141592654
  521.  
  522.     int    sintable[256];
  523.     float    i;
  524.  
  525.     for(i=0;i<2*PI;i+=2*PI/256)
  526.         sintable[i]=(int)30000*sin(i);
  527. -----------------------------------------------
  528.  
  529.  
  530.     TO CALCULATE Y=X*SIN(ANGLE);
  531.  
  532.     y=x*sintable[angle];    //Where you would have to represent represent your
  533.                 //angles in values from 0->255 instead of
  534.                 //0->2*PI =)
  535.  
  536. // Now, your y is 30000 times too large, and to make the calculation
  537. // correct just divide by 30000, however it might pay off to use some assembly
  538. // here as you can gain a lot by using a registers only loop and using
  539. // a swap command to correct your calculations.
  540. //(BTW: you would have to multiply with 32767 to make this work with
  541. // acceptable accuracy )
  542.  
  543. >                                                                               
  544. > Say, does it make much difference (in performance) whether you use integer or 
  545. > floating point math in any case?
  546.     This depends, on my A4000 you probably wouldn't gain much =)
  547.     But, on a machine without an FPU this gives a great speed increase
  548.     FOR THE CALCULATIONS, but usually you'll spend much more time 
  549.     drawing lines than calculating points, so the conclusion is
  550.     that is you've got a fast FPU, dont bother.....
  551.  
  552. > BTW, I'm using C, so if you have any bits of integer math code handy in that
  553. > language, could you please send me some? 
  554.     I'm coding assembly language, so ehhhhhhh... I don't think so.
  555.     My routines would be very hard to include in a C program I think.
  556.     (My calculation loop uses all available registers except the 
  557.     stack pointer =) )
  558.  
  559. > Thanx for... well, whatever you can tell me! ;)
  560.  
  561.     You are welcome =)
  562.  
  563. ------------------------------------------------------------
  564. INCLUDE "disclaimer.i"                       Zrouoggathog
  565. Olav 'Warp' Kalgraf                          Cthulhu in '96!
  566. internet: olavka@ifi.uio.no                  Hasoithshuna
  567.  
  568. --------------------...
  569.  
  570. Scaled integers work just fine.  Remember your algebra:
  571.  
  572. a = b + c 
  573. xa = xb + xc
  574. a = (xb + xc)/x
  575.  
  576.  
  577. Basically you can take any algebraic expression and multiply by a constant
  578. then divide by the constant and get the same (truncated) answer.
  579.  
  580. 16-bit integers (shorts) only give 4 positions of accuracy whereas 32-bit
  581. ints (longs) will give 9.  The trade off is speed.  You also need to be
  582. sure that your integer math won't overflow.  Doing things like squares
  583. and cubes can make some pretty big numbers in scaled integers.
  584.  
  585. Here's a small example:
  586. #define FUNC(b,c) (b*5 + c*10)
  587.  
  588.  main()
  589.  {
  590.  float af,bf=4.56,cf=7.89;
  591.  long ai,bi,ci;
  592.  float factor = 1000;
  593.  af = FUNC(bf,cf);
  594.  bi = bf*factor;
  595.  ci = cf*factor;
  596.  ai = FUNC(bi,ci);
  597.  printf("Answers are: %g, %g\n",af,ai/factor);
  598.  }
  599.  
  600.  
  601. -- 
  602. -----------------------------------------------------------------------------
  603.  black@beno.CSS.GOV             land line: 407-676-2923  | I want a computer
  604.  real home: Melbourne, FL       home line: 407-242-8619  | that does it all!
  605.  CSI Inc, Computer Software Innovations, Palm Bay, FL
  606. -----------------------------------------------------------------------------
  607.  
  608. -------------....
  609.  
  610. In article <1993Feb12.110623.6317@abo.fi> MSAASTAMOINE@FINABO.ABO.FI (Mika Saastamoinen Tkkk) writes:
  611. > Hi ya'all!
  612. > I was wondering if someone could explain to me the basic principles of integer
  613. > math. Specifically, I'm thinking of the kind of math one uses in 3D (vector)
  614. > graphics programming. Since I'm not so awfully hot on math I thought I'd ask 
  615. > you Gurus about this! O:)
  616. > Let's say I'm thinking of the floating point number '1.234567890': How do I
  617. > convert that to integer without losing accuracy too much and how would I go
  618. > about using that integer number in various calculation (mult,div,add,subs) 
  619. > with (maybe) one or more of the same kind of integer numbers? 
  620.  
  621. You can't convert small FP numbers like that to integer, but consider
  622. fixed-point maths, where you arbitrarily create a decimal point somewhere
  623. in a 32-bit integer. You still perform "integer" operations on numbers, but
  624. you've shifted your range from (say) 2**0 - 2**32-1 to 2**-8 - 2**24-1.
  625.  
  626.                         Michael Warner (atheist) - Phoenix MicroTechnologies
  627.                         cbmvax.commodore.com!cbmehq!cbmaus!phoenix!michaelw
  628.  
  629.    "In the blood of Eden
  630.     Lie the woman and the man
  631.     I see the man in the woman
  632.     And the woman in the man"
  633.  
  634.                 - Peter Gabriel
  635.  
  636. --------------...
  637.  
  638. lavelle@convex.com (Brent LaVelle) writes:
  639. >MSAASTAMOINE@FINABO.ABO.FI (Mika Saastamoinen Tkkk) writes:
  640.  
  641. >>I was wondering if someone could explain to me the basic principles of integer
  642. >>math.
  643.  
  644. >>and how would I go
  645. >>about using that integer number in various calculation (mult,div,add,subs) 
  646. >>with (maybe) one or more of the same kind of integer numbers? 
  647.  
  648. >The integer numbers are transformed into fixed point numbers by using using
  649. >the integer and clearing another 16bit value (hopefully behind the 16bit
  650. >integer).  Now you simply preform the integer 32bit operations.
  651.  
  652. Just to clarify Brent's description...
  653.  
  654. Say "a" and "b" is your 32-bit value consisting of 16 bits of integer
  655. component and 16 bits of fractional component.  To ADD a and b, to get c,
  656. simply use:
  657.  
  658.     c=a+b;
  659.  
  660. BUT, to multiply a by b to get c, you need:
  661.  
  662.     c=a*b/65536;
  663.  
  664.  
  665. Taking whatever precautions to avoid overflow, and whatever advantage of
  666. machine instructions your machine requires that your optimising compiler
  667. doesn't support...
  668.  
  669. I think it's about time to implement a C++ template for Fixed integers...
  670. Anyone interested should contact me.
  671.  
  672.  
  673. --
  674. Warwick
  675.   _-_|\      warwick@cs.uq.oz.au            /Disclaimer:
  676.  /     * <-- Computer Science Department,  /  
  677.  \_.-._/     University of Queensland,    /   C references are NULL && void*
  678.       v      Brisbane, Australia.        /  
  679.  
  680. --------------...
  681.  
  682. In article <12083@uqcspe.cs.uq.oz.au> warwick@cs.uq.oz.au writes:
  683. >lavelle@convex.com (Brent LaVelle) writes:
  684.  [Stuff deleted]
  685. >Just to clarify Brent's description...
  686. >
  687. >Say "a" and "b" is your 32-bit value consisting of 16 bits of integer
  688. >component and 16 bits of fractional component.  To ADD a and b, to get c,
  689. >simply use:
  690. >
  691. >    c=a+b;
  692. >
  693. >BUT, to multiply a by b to get c, you need:
  694. >
  695. >    c=a*b/65536;
  696.  
  697. That is a good point.  However, to "fix" the decmal point you simply shift
  698. the number by the size of your fraction integer.  That's a mouthfull, here
  699. is the example, I'll go back to my original notation where fixed point
  700. numbers are represented as (IntegerPart)(FractionalPart)
  701.  
  702. This is a long multiplication in base 2^16.
  703.  
  704. (4)(6) * (2)(3)
  705.  
  706.     ( 4)( 6)
  707.  *  ( 2)( 3)
  708. ===========
  709.     (12)(18)  <- fractional part * whole top number
  710. ( 6)(12)      <- integer part * whole top number
  711. ============
  712. ( 6)(24)      <- Your answer.
  713.         (18)  <- error (if >= 2^15 you may want to bump up the answer
  714.  ^^------------- if this number overflows you have an overflow, inturrupt
  715.                  or set the overflow flag is set, whatever the convention is.
  716.                  Furthermore it can happen after the multiply OR on a carry
  717.                  when you add.
  718.  
  719. Also note if you have 64 bit operations on your processor you can skip
  720. a lot of stuff, eg:
  721.  
  722.         ( 4)( 6)
  723.  *      ( 2)( 3)
  724. ===========
  725. (00)( 6)(24)      <- Your answer.
  726.             (18)  <- error (if >= 2^15 you may want to bump up the answer
  727.  ^^------------- if this number is not zero you have an overflow, inturrupt
  728.                  or set the overflow flag is set, whatever the convention is.
  729.                  Furthermore it can happen after the multiply OR on a carry
  730.                  when you add.
  731.  
  732. >Taking whatever precautions to avoid overflow, and whatever advantage of
  733. >machine instructions your machine requires that your optimising compiler
  734. >doesn't support...
  735. >
  736. >I think it's about time to implement a C++ template for Fixed integers...
  737. >Anyone interested should contact me.
  738. Be sure to make it in-line stuff.  The call overhead will kill you if
  739. you try to use functions.
  740. >
  741.  
  742. - Brent LaVelle
  743. lavelle@convex.com
  744.  
  745. ---------------...
  746.  
  747. Here's a quick way to do these fixed point integers in 68000 assembly:
  748.  
  749. (assume the two numbers are passed on the stack as usual)
  750.  
  751.     xdef _Fixed_mul:
  752. _Fixed_mul:
  753.     move.w 4(a7),d0
  754.     mulu.w 10(a7),d0    ; d0 = a1*b2
  755.     move.w 6(a7),d1
  756.     mulu.w 8(a7),d1        ; d1 = a2*b1
  757.     add.l d1,d0        ; d0 = a1*b2+a2*b1
  758.     move.w 4(a7),d1
  759.     mulu.w 8(a7),d1        ; d1 = a1*b1
  760.     sll.l #8,d1
  761.     sll.l #8,d1        ; d1 = d1*2^16
  762.     add.l d1,d0
  763.     rts
  764.  
  765. This will work for unsigned, 32-bit fixed points.  If you use 2's
  766. complement to represent signed ones, it will work for signed ones,
  767. too.  Two's complement is also useful for addition/subtraction!  Any
  768. overflows are ignored (integer part of the result is mod 2^16).  It
  769. would be easy to modify this function to allow you to signal an
  770. overflow.  Anyway, this is the ideal which the compiler is striving
  771. for.  Just use this little routine, and worry no more about sloppy
  772. compilers!  You can even have it pass the arguments in registers, but
  773. this actually will not speed things up much, since it needs to use
  774. more registers, and has to save them on the stack anyway.  SAS/C
  775. allows such register argument passing.
  776.     For such a simple routine, I'd say assembly code is definitely
  777. warranted.  The tricky part is printing these numbers out, but hey,
  778. who cares how slow that is?  The best way is probably to convert them
  779. to floating point.
  780.  
  781. --
  782. +----------------------------Ren & Stimpy--------------------------------+
  783. | "Psst. Hey Guido. It's all so clear to me now. I'm the keeper of the   |
  784. | cheese. And you're the lemon merchant. Get it? And he knows it. That's |
  785. | why he's gonna kill us. So we gotta beat it. Yeah. Before he lets      |
  786. | loose the marmosets on us! Don't worry, little missy! I'll save you!"  |
  787. +--------------- Quantum Seep -- kopnicky@owlnet.rice.edu ---------------+
  788.