1 <?xml version=
"1.0" encoding=
"UTF-8"?>
4 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 Copyright 2008 by Sun Microsystems, Inc.
8 OpenOffice.org - a multi-platform office productivity suite
10 $RCSfile: math.xsl,v $
14 This file is part of OpenOffice.org.
16 OpenOffice.org is free software: you can redistribute it and/or modify
17 it under the terms of the GNU Lesser General Public License version 3
18 only, as published by the Free Software Foundation.
20 OpenOffice.org is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU Lesser General Public License version 3 for more details
24 (a copy is included in the LICENSE file that accompanied this code).
26 You should have received a copy of the GNU Lesser General Public License
27 version 3 along with OpenOffice.org. If not, see
28 <http://www.openoffice.org/license.html>
29 for a copy of the LGPLv3 License.
33 xslt math lib by Wind Li
35 sin(x,rounding-factor=100)
36 cos(x,rounding-factor=100)
37 tan(x,rounding-factor=100)
38 ctan(x,rounding-factor=100)
39 atan2(x, y ,rounding-factor=100)
40 atan(x,rounding-factor=100)
41 acos(x,rounding-factor=100)
42 asin(x,rounding-factor=100)
46 power(x,power(interger only), rounding-factor=100)
47 sqrt(x, rounding-factor=100)
48 convert2radian(x,rounding-factor=100)
49 convert2degree(x,rounding-factor=100)
50 convert2fd(x,rounding-factor=100)
52 <xsl:stylesheet version=
"1.0" xmlns:
xsl=
"http://www.w3.org/1999/XSL/Transform" xmlns:
draw=
"http://openoffice.org/2000/drawing" xmlns:
o=
"urn:schemas-microsoft-com:office:office" xmlns:
svg=
"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:
v=
"urn:schemas-microsoft-com:vml" xmlns:
w10=
"urn:schemas-microsoft-com:office:word" xmlns:
w=
"http://schemas.microsoft.com/office/word/2003/wordml" xmlns:
text=
"http://openoffice.org/2000/text" xmlns:
style=
"http://openoffice.org/2000/style" xmlns:
fo=
"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:
office=
"http://openoffice.org/2000/office" exclude-result-prefixes=
"draw svg style office fo text">
53 <xsl:variable name=
"pi" select=
"3.1416"/>
54 <xsl:template name=
"math-test">
56 <xsl:call-template name=
"sin">
57 <xsl:with-param name=
"x" select=
"34.8"/>
58 <xsl:with-param name=
"rounding-factor" select=
"100000"/>
61 <xsl:call-template name=
"cos">
62 <xsl:with-param name=
"x" select=
"34.8"/>
63 <xsl:with-param name=
"rounding-factor" select=
"100000"/>
66 <xsl:call-template name=
"atan">
67 <xsl:with-param name=
"x" select=
"2.74"/>
68 <xsl:with-param name=
"rounding-factor" select=
"100000"/>
71 <xsl:call-template name=
"acos">
72 <xsl:with-param name=
"x" select=
"0.5"/>
73 <xsl:with-param name=
"rounding-factor" select=
"100000"/>
76 <xsl:call-template name=
"asin">
77 <xsl:with-param name=
"x" select=
"0.5"/>
78 <xsl:with-param name=
"rounding-factor" select=
"100000"/>
81 <xsl:call-template name=
"sqrt">
82 <xsl:with-param name=
"x" select=
"1328.3414"/>
83 <xsl:with-param name=
"rounding-factor" select=
"100000"/>
86 <!-- public functions start -->
87 <xsl:template name=
"sin">
88 <xsl:param name=
"x" select=
"0"/>
89 <xsl:param name=
"rounding-factor" select=
"100"/>
90 <xsl:variable name=
"angle" select=
"$x * 180 div $pi "/>
91 <xsl:variable name=
"mod-angle" select=
"$angle mod 360"/>
92 <xsl:variable name=
"sinx">
93 <xsl:call-template name=
"sin-private">
94 <xsl:with-param name=
"x" select=
" ( $angle mod 360 ) * $pi div 180 "/>
97 <xsl:value-of select=
" round ( number($sinx) * $rounding-factor ) div $rounding-factor"/>
99 <xsl:template name=
"cos">
100 <xsl:param name=
"x" select=
"0"/>
101 <xsl:param name=
"rounding-factor" select=
"100"/>
102 <xsl:variable name=
"angle" select=
"$x * 180 div $pi "/>
103 <xsl:variable name=
"mod-angle" select=
"$angle mod 360"/>
104 <xsl:variable name=
"cosx">
105 <xsl:call-template name=
"cos-private">
106 <xsl:with-param name=
"x" select=
" ( $angle mod 360 ) * $pi div 180 "/>
109 <xsl:value-of select=
" round ( number($cosx) * $rounding-factor ) div $rounding-factor"/>
111 <xsl:template name=
"tan">
112 <xsl:param name=
"x" select=
"0"/>
113 <xsl:param name=
"rounding-factor" select=
"100"/>
114 <xsl:variable name=
"sinx">
115 <xsl:call-template name=
"sin">
116 <xsl:with-param name=
"x" select=
"$x"/>
117 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor * 10"/>
120 <xsl:variable name=
"cosx">
121 <xsl:call-template name=
"cos">
122 <xsl:with-param name=
"x" select=
"$x"/>
123 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor * 10"/>
127 <xsl:when test=
" $cosx = 0 ">
128 <xsl:message>tan error : tan(
<xsl:value-of select=
"$x"/>) is infinite!
</xsl:message>
129 <xsl:value-of select=
"63535"/>
132 <xsl:value-of select=
" round( $sinx div $cosx * $rounding-factor) div $rounding-factor"/>
136 <xsl:template name=
"ctan">
137 <xsl:param name=
"x" select=
"0"/>
138 <xsl:param name=
"rounding-factor" select=
"100"/>
139 <xsl:variable name=
"sinx">
140 <xsl:call-template name=
"sin">
141 <xsl:with-param name=
"x" select=
"$x"/>
142 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor * 10"/>
145 <xsl:variable name=
"cosx">
146 <xsl:call-template name=
"cos">
147 <xsl:with-param name=
"x" select=
"$x"/>
148 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor * 10"/>
152 <xsl:when test=
" $sinx = 0 ">
153 <xsl:message>tan error : tan(
<xsl:value-of select=
"$x"/>) is infinite!
</xsl:message>
154 <xsl:value-of select=
"63535"/>
157 <xsl:value-of select=
" round( $cosx div $sinx * $rounding-factor) div $rounding-factor"/>
161 <xsl:template name=
"atan">
162 <xsl:param name=
"x" select=
"0"/>
163 <xsl:param name=
"rounding-factor" select=
"100"/>
165 <xsl:when test=
"$x = 0">
166 <xsl:value-of select=
"0"/>
168 <xsl:when test=
"$x < 0">
169 <xsl:variable name=
"atan-x">
170 <xsl:call-template name=
"atan">
171 <xsl:with-param name=
"x" select=
" -1 * $x"/>
172 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor"/>
175 <xsl:value-of select=
"-1 * $atan-x"/>
177 <xsl:when test=
"$x > 1">
178 <xsl:variable name=
"atan-div-x">
179 <xsl:call-template name=
"atan">
180 <xsl:with-param name=
"x" select=
"1 div $x "/>
181 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor"/>
184 <xsl:value-of select=
" $pi div 2 - $atan-div-x"/>
187 <xsl:variable name=
"arctanx">
188 <xsl:call-template name=
"atan-private">
189 <xsl:with-param name=
"x" select=
" $x "/>
192 <xsl:value-of select=
" round ( number($arctanx) * $rounding-factor ) div $rounding-factor"/>
196 <xsl:template name=
"atan2">
197 <xsl:param name=
"x"/>
198 <xsl:param name=
"y"/>
199 <xsl:param name=
"rounding-factor" select=
"100"/>
201 <xsl:when test=
"$x = 0">
202 <xsl:value-of select=
" $pi div 2"/>
205 <xsl:call-template name=
"atan">
206 <xsl:with-param name=
"x" select=
"$y div $x"/>
207 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor"/>
212 <xsl:template name=
"acos">
213 <xsl:param name=
"x"/>
214 <xsl:param name=
"rounding-factor" select=
"100"/>
215 <xsl:variable name=
"abs-x">
216 <xsl:call-template name=
"abs">
217 <xsl:with-param name=
"x" select=
"$x"/>
221 <xsl:when test=
"$abs-x > 1">
222 <xsl:message>acos error : abs(
<xsl:value-of select=
"$x"/>) greate then
1 !
</xsl:message>
225 <xsl:call-template name=
"atan2">
226 <xsl:with-param name=
"x" select=
"$x"/>
227 <xsl:with-param name=
"y">
228 <xsl:call-template name=
"sqrt">
229 <xsl:with-param name=
"x" select=
"1 - $x * $x"/>
230 <xsl:with-param name=
"rounding-factor" select=
" concat($rounding-factor,'0') "/>
237 <xsl:template name=
"asin">
238 <xsl:param name=
"x"/>
239 <xsl:param name=
"rounding-factor" select=
"100"/>
240 <xsl:variable name=
"abs-x">
241 <xsl:call-template name=
"abs">
242 <xsl:with-param name=
"x" select=
"$x"/>
246 <xsl:when test=
"$abs-x > 1">
247 <xsl:message>asin error : abs(
<xsl:value-of select=
"$x"/>) greate then
1 !
</xsl:message>
250 <xsl:call-template name=
"atan2">
251 <xsl:with-param name=
"y" select=
"$x"/>
252 <xsl:with-param name=
"x">
253 <xsl:call-template name=
"sqrt">
254 <xsl:with-param name=
"x" select=
"1 - $x * $x"/>
255 <xsl:with-param name=
"rounding-factor" select=
" concat($rounding-factor,'0') "/>
262 <xsl:template name=
"abs">
263 <xsl:param name=
"x"/>
265 <xsl:when test=
"$x > 0">
266 <xsl:value-of select=
"$x"/>
269 <xsl:value-of select=
"$x * -1"/>
273 <xsl:template name=
"max">
274 <xsl:param name=
"x1"/>
275 <xsl:param name=
"x2"/>
277 <xsl:when test=
"$x1 > $x2">
278 <xsl:value-of select=
"$x1"/>
281 <xsl:value-of select=
"$x2"/>
285 <xsl:template name=
"min">
286 <xsl:param name=
"x1"/>
287 <xsl:param name=
"x2"/>
289 <xsl:when test=
"$x1 < $x2">
290 <xsl:value-of select=
"$x1"/>
293 <xsl:value-of select=
"$x2"/>
297 <xsl:template name=
"power">
298 <xsl:param name=
"x"/>
299 <xsl:param name=
"y" select=
"1"/>
300 <xsl:param name=
"rounding-factor" select=
"100"/>
301 <!-- z is a private param -->
302 <xsl:param name=
"z" select=
"1"/>
304 <xsl:when test=
"$y > 0">
305 <xsl:call-template name=
"power">
306 <xsl:with-param name=
"x" select=
"$x"/>
307 <xsl:with-param name=
"y" select=
"$y - 1"/>
308 <xsl:with-param name=
"z" select=
"$z * $x"/>
309 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor"/>
313 <xsl:value-of select=
" round( $z * $rounding-factor) div $rounding-factor"/>
317 <xsl:template name=
"sqrt">
318 <xsl:param name=
"x"/>
319 <xsl:param name=
"rounding-factor" select=
"100"/>
321 <xsl:when test=
"$x = 0">0</xsl:when>
322 <xsl:when test=
"$x < 0">
323 <xsl:message>sqrt error :
<xsl:value-of select=
"$x"/> less then
0!
</xsl:message>
326 <xsl:call-template name=
"sqrt-private">
327 <xsl:with-param name=
"x" select=
"$x"/>
328 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor"/>
333 <!-- public functions end -->
343 <xsl:template name=
"sin-private">
344 <xsl:param name=
"x" select=
"0"/>
345 <xsl:param name=
"n" select=
"0"/>
346 <xsl:param name=
"nx" select=
"1"/>
347 <xsl:param name=
"sign" select=
"1"/>
348 <xsl:param name=
"max-n" select=
"20"/>
349 <xsl:param name=
"sinx" select=
"0"/>
351 <xsl:when test=
"not ($max-n > $n) or $nx = 0 ">
352 <xsl:value-of select=
"$sinx"/>
354 <xsl:when test=
"$n = 0">
355 <xsl:call-template name=
"sin-private">
356 <xsl:with-param name=
"x" select=
"$x"/>
357 <xsl:with-param name=
"n" select=
"$n + 1"/>
358 <xsl:with-param name=
"sign" select=
"$sign * -1"/>
359 <xsl:with-param name=
"max-n" select=
"$max-n"/>
360 <xsl:with-param name=
"nx" select=
"$x "/>
361 <xsl:with-param name=
"sinx" select=
"$sinx + $x"/>
365 <xsl:variable name=
"new-nx" select=
"($nx * $x * $x) div ( 2 * $n ) div ( 2 * $n + 1) "/>
366 <xsl:call-template name=
"sin-private">
367 <xsl:with-param name=
"x" select=
"$x"/>
368 <xsl:with-param name=
"n" select=
"$n + 1"/>
369 <xsl:with-param name=
"sign" select=
"$sign * -1"/>
370 <xsl:with-param name=
"max-n" select=
"$max-n"/>
371 <xsl:with-param name=
"nx" select=
" $new-nx "/>
372 <xsl:with-param name=
"sinx" select=
"$sinx + $new-nx * $sign"/>
377 <xsl:template name=
"cos-private">
378 <xsl:param name=
"x" select=
"0"/>
379 <xsl:param name=
"n" select=
"0"/>
380 <xsl:param name=
"nx" select=
"1"/>
381 <xsl:param name=
"sign" select=
"1"/>
382 <xsl:param name=
"max-n" select=
"20"/>
383 <xsl:param name=
"cosx" select=
"0"/>
385 <xsl:when test=
"not ($max-n > $n) or $nx = 0 ">
386 <xsl:value-of select=
"$cosx"/>
388 <xsl:when test=
"$n = 0">
389 <xsl:call-template name=
"cos-private">
390 <xsl:with-param name=
"x" select=
"$x"/>
391 <xsl:with-param name=
"n" select=
"$n + 1"/>
392 <xsl:with-param name=
"sign" select=
"$sign * -1"/>
393 <xsl:with-param name=
"max-n" select=
"$max-n"/>
394 <xsl:with-param name=
"nx" select=
" 1 "/>
395 <xsl:with-param name=
"cosx" select=
"1"/>
399 <xsl:variable name=
"new-nx" select=
"($nx * $x * $x) div ( 2 * $n -1 ) div ( 2 * $n ) "/>
400 <xsl:call-template name=
"cos-private">
401 <xsl:with-param name=
"x" select=
"$x"/>
402 <xsl:with-param name=
"n" select=
"$n + 1"/>
403 <xsl:with-param name=
"sign" select=
"$sign * -1"/>
404 <xsl:with-param name=
"max-n" select=
"$max-n"/>
405 <xsl:with-param name=
"nx" select=
" $new-nx "/>
406 <xsl:with-param name=
"cosx" select=
"$cosx + $new-nx * $sign"/>
411 <xsl:template name=
"atan-private">
412 <xsl:param name=
"x" select=
"0"/>
413 <xsl:param name=
"n" select=
"0"/>
414 <xsl:param name=
"nx" select=
"1"/>
415 <xsl:param name=
"sign" select=
"1"/>
416 <xsl:param name=
"max-n" select=
"40"/>
417 <xsl:param name=
"arctanx" select=
"0"/>
419 <xsl:when test=
"not ($max-n > $n) or $nx = 0 ">
420 <xsl:value-of select=
"$arctanx"/>
422 <xsl:when test=
"$n = 0">
423 <xsl:call-template name=
"atan-private">
424 <xsl:with-param name=
"x" select=
"$x"/>
425 <xsl:with-param name=
"n" select=
"$n + 1"/>
426 <xsl:with-param name=
"sign" select=
"$sign * -1"/>
427 <xsl:with-param name=
"max-n" select=
"$max-n"/>
428 <xsl:with-param name=
"nx" select=
"$x "/>
429 <xsl:with-param name=
"arctanx" select=
"$arctanx + $x"/>
433 <xsl:variable name=
"new-nx" select=
" $nx * $x * $x "/>
434 <xsl:call-template name=
"atan-private">
435 <xsl:with-param name=
"x" select=
"$x"/>
436 <xsl:with-param name=
"n" select=
"$n + 1"/>
437 <xsl:with-param name=
"sign" select=
"$sign * -1"/>
438 <xsl:with-param name=
"max-n" select=
"$max-n"/>
439 <xsl:with-param name=
"nx" select=
" $new-nx "/>
440 <xsl:with-param name=
"arctanx" select=
"$arctanx + $new-nx div (2 * $n +1) * $sign"/>
445 <xsl:template name=
"sqrt-private">
446 <xsl:param name=
"x"/>
447 <xsl:param name=
"rounding-factor" select=
"100"/>
448 <xsl:variable name=
"shift" select=
"string-length( $rounding-factor)"/>
449 <xsl:variable name=
"power">
450 <xsl:call-template name=
"power">
451 <xsl:with-param name=
"x" select=
"100"/>
452 <xsl:with-param name=
"y" select=
"$shift"/>
453 <xsl:with-param name=
"rounding-factor" select=
"1"/>
456 <xsl:variable name=
"integer-x" select=
" round( $power * $x )"/>
457 <xsl:variable name=
"integer-quotient">
458 <xsl:call-template name=
"integer-sqrt">
459 <xsl:with-param name=
"x" select=
"$integer-x"/>
460 <xsl:with-param name=
"length" select=
" string-length( $integer-x ) "/>
461 <xsl:with-param name=
"curr-pos" select=
" 2 - (round (string-length( $integer-x ) div 2 ) * 2 - string-length( $integer-x ) ) "/>
464 <xsl:variable name=
"power-10">
465 <xsl:call-template name=
"power">
466 <xsl:with-param name=
"x" select=
"10"/>
467 <xsl:with-param name=
"y" select=
"$shift - 1"/>
468 <xsl:with-param name=
"rounding-factor" select=
"1"/>
471 <xsl:value-of select=
" round( $integer-quotient div 10) div $power-10 "/>
473 <xsl:template name=
"integer-sqrt">
474 <xsl:param name=
"x"/>
475 <xsl:param name=
"length"/>
476 <xsl:param name=
"curr-pos"/>
477 <xsl:param name=
"last-quotient" select=
"0"/>
479 <xsl:when test=
"$curr-pos > $length">
480 <xsl:value-of select=
"$last-quotient"/>
483 <xsl:variable name=
"curr-x" select=
"substring( $x, 1, $curr-pos )"/>
484 <xsl:variable name=
"new-quotient">
485 <xsl:call-template name=
"get-one-sqrt-digit">
486 <xsl:with-param name=
"x" select=
"$curr-x"/>
487 <xsl:with-param name=
"last-quotient" select=
"$last-quotient"/>
488 <xsl:with-param name=
"n" select=
"5"/>
489 <xsl:with-param name=
"direct" select=
"0"/>
492 <xsl:call-template name=
"integer-sqrt">
493 <xsl:with-param name=
"x" select=
"$x"/>
494 <xsl:with-param name=
"length" select=
"$length"/>
495 <xsl:with-param name=
"curr-pos" select=
"$curr-pos + 2"/>
496 <xsl:with-param name=
"last-quotient" select=
"number($new-quotient)"/>
501 <xsl:template name=
"get-one-sqrt-digit">
502 <xsl:param name=
"x"/>
503 <xsl:param name=
"last-quotient"/>
504 <xsl:param name=
"n"/>
505 <xsl:param name=
"direct" select=
"1"/>
506 <xsl:variable name=
"quotient" select=
" concat( $last-quotient, $n) "/>
507 <xsl:variable name=
"accumulate" select=
"$quotient * $quotient "/>
509 <xsl:when test=
"$accumulate = $x">
510 <xsl:value-of select=
"concat($last-quotient , $n )"/>
512 <xsl:when test=
"$direct = 0 and $accumulate < $x">
513 <xsl:call-template name=
"get-one-sqrt-digit">
514 <xsl:with-param name=
"x" select=
"$x"/>
515 <xsl:with-param name=
"last-quotient" select=
"$last-quotient"/>
516 <xsl:with-param name=
"n" select=
"$n + 1"/>
517 <xsl:with-param name=
"direct" select=
"1"/>
520 <xsl:when test=
"$direct = 0 and $accumulate > $x">
521 <xsl:call-template name=
"get-one-sqrt-digit">
522 <xsl:with-param name=
"x" select=
"$x"/>
523 <xsl:with-param name=
"last-quotient" select=
"$last-quotient"/>
524 <xsl:with-param name=
"n" select=
"$n - 1"/>
525 <xsl:with-param name=
"direct" select=
"-1"/>
528 <xsl:when test=
" $accumulate * $direct < $x * $direct ">
529 <xsl:call-template name=
"get-one-sqrt-digit">
530 <xsl:with-param name=
"x" select=
"$x"/>
531 <xsl:with-param name=
"last-quotient" select=
"$last-quotient"/>
532 <xsl:with-param name=
"n" select=
"$n+ $direct"/>
533 <xsl:with-param name=
"direct" select=
"$direct"/>
536 <xsl:when test=
"not($n < 9) or $n = -1">
537 <xsl:value-of select=
"concat($last-quotient , $n - $direct) "/>
539 <xsl:when test=
"$direct = 1">
540 <xsl:value-of select=
"concat($last-quotient , $n - 1) "/>
543 <xsl:value-of select=
"concat($last-quotient , $n) "/>
547 <xsl:template name=
"convert2redian">
548 <xsl:param name=
"x" select=
"'0'"/>
549 <xsl:param name=
"rounding-factor" select=
"100"/>
551 <xsl:when test=
"contains($x,'deg')">
552 <xsl:value-of select=
"round($rounding-factor * number(substring-before($x, 'deg') div 180 * $pi)) div $rounding-factor"/>
554 <xsl:when test=
"contains($x,'fd')">
555 <xsl:value-of select=
"round($rounding-factor * number(substring-before($x, 'fd') div 180 div 65536 * $pi)) div $rounding-factor"/>
558 <xsl:value-of select=
"round($rounding-factor * number($x) div 180 * $pi) div $rounding-factor"/>
562 <xsl:template name=
"convert2degree">
563 <xsl:param name=
"x" select=
"'0'"/>
564 <xsl:param name=
"rounding-factor" select=
"100"/>
566 <xsl:when test=
"contains($x,'deg')">
567 <xsl:value-of select=
"round($rounding-factor * substring-before($x,'deg')) div $rounding-factor"/>
569 <xsl:when test=
"contains($x,'fd')">
570 <xsl:value-of select=
"round($rounding-factor * number(substring-before($x, 'fd')) div 65536 ) div $rounding-factor"/>
573 <xsl:value-of select=
"round($rounding-factor * number($x) * 180 div $pi) div $rounding-factor"/>
577 <xsl:template name=
"convert2fd">
578 <xsl:param name=
"x" select=
"'0'"/>
579 <xsl:param name=
"rounding-factor" select=
"100"/>
581 <xsl:when test=
"contains($x,'deg')">
582 <xsl:value-of select=
"round($rounding-factor * number(substring-before($x, 'deg') * 65535)) div $rounding-factor"/>
584 <xsl:when test=
"contains($x,'fd')">
585 <xsl:value-of select=
"round($rounding-factor * number(substring-before($x, 'fd'))) div $rounding-factor"/>
588 <xsl:value-of select=
"round($rounding-factor * number($x) * 180 div $pi * 65535) div $rounding-factor"/>