1 <?xml version=
"1.0" encoding=
"UTF-8"?>
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 xslt math lib by Wind Li
22 sin(x,rounding-factor=100)
23 cos(x,rounding-factor=100)
24 tan(x,rounding-factor=100)
25 ctan(x,rounding-factor=100)
26 atan2(x, y ,rounding-factor=100)
27 atan(x,rounding-factor=100)
28 acos(x,rounding-factor=100)
29 asin(x,rounding-factor=100)
33 power(x,power(integer only), rounding-factor=100)
34 sqrt(x, rounding-factor=100)
35 convert2radian(x,rounding-factor=100)
36 convert2degree(x,rounding-factor=100)
37 convert2fd(x,rounding-factor=100)
39 <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">
40 <xsl:variable name=
"pi" select=
"3.1416"/>
41 <xsl:template name=
"math-test">
43 <xsl:call-template name=
"sin">
44 <xsl:with-param name=
"x" select=
"34.8"/>
45 <xsl:with-param name=
"rounding-factor" select=
"100000"/>
48 <xsl:call-template name=
"cos">
49 <xsl:with-param name=
"x" select=
"34.8"/>
50 <xsl:with-param name=
"rounding-factor" select=
"100000"/>
53 <xsl:call-template name=
"atan">
54 <xsl:with-param name=
"x" select=
"2.74"/>
55 <xsl:with-param name=
"rounding-factor" select=
"100000"/>
58 <xsl:call-template name=
"acos">
59 <xsl:with-param name=
"x" select=
"0.5"/>
60 <xsl:with-param name=
"rounding-factor" select=
"100000"/>
63 <xsl:call-template name=
"asin">
64 <xsl:with-param name=
"x" select=
"0.5"/>
65 <xsl:with-param name=
"rounding-factor" select=
"100000"/>
68 <xsl:call-template name=
"sqrt">
69 <xsl:with-param name=
"x" select=
"1328.3414"/>
70 <xsl:with-param name=
"rounding-factor" select=
"100000"/>
73 <!-- public functions start -->
74 <xsl:template name=
"sin">
75 <xsl:param name=
"x" select=
"0"/>
76 <xsl:param name=
"rounding-factor" select=
"100"/>
77 <xsl:variable name=
"angle" select=
"$x * 180 div $pi "/>
78 <xsl:variable name=
"mod-angle" select=
"$angle mod 360"/>
79 <xsl:variable name=
"sinx">
80 <xsl:call-template name=
"sin-private">
81 <xsl:with-param name=
"x" select=
" ( $angle mod 360 ) * $pi div 180 "/>
84 <xsl:value-of select=
" round ( number($sinx) * $rounding-factor ) div $rounding-factor"/>
86 <xsl:template name=
"cos">
87 <xsl:param name=
"x" select=
"0"/>
88 <xsl:param name=
"rounding-factor" select=
"100"/>
89 <xsl:variable name=
"angle" select=
"$x * 180 div $pi "/>
90 <xsl:variable name=
"mod-angle" select=
"$angle mod 360"/>
91 <xsl:variable name=
"cosx">
92 <xsl:call-template name=
"cos-private">
93 <xsl:with-param name=
"x" select=
" ( $angle mod 360 ) * $pi div 180 "/>
96 <xsl:value-of select=
" round ( number($cosx) * $rounding-factor ) div $rounding-factor"/>
98 <xsl:template name=
"tan">
99 <xsl:param name=
"x" select=
"0"/>
100 <xsl:param name=
"rounding-factor" select=
"100"/>
101 <xsl:variable name=
"sinx">
102 <xsl:call-template name=
"sin">
103 <xsl:with-param name=
"x" select=
"$x"/>
104 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor * 10"/>
107 <xsl:variable name=
"cosx">
108 <xsl:call-template name=
"cos">
109 <xsl:with-param name=
"x" select=
"$x"/>
110 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor * 10"/>
114 <xsl:when test=
" $cosx = 0 ">
115 <xsl:message>tan error : tan(
<xsl:value-of select=
"$x"/>) is infinite!
</xsl:message>
116 <xsl:value-of select=
"63535"/>
119 <xsl:value-of select=
" round( $sinx div $cosx * $rounding-factor) div $rounding-factor"/>
123 <xsl:template name=
"ctan">
124 <xsl:param name=
"x" select=
"0"/>
125 <xsl:param name=
"rounding-factor" select=
"100"/>
126 <xsl:variable name=
"sinx">
127 <xsl:call-template name=
"sin">
128 <xsl:with-param name=
"x" select=
"$x"/>
129 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor * 10"/>
132 <xsl:variable name=
"cosx">
133 <xsl:call-template name=
"cos">
134 <xsl:with-param name=
"x" select=
"$x"/>
135 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor * 10"/>
139 <xsl:when test=
" $sinx = 0 ">
140 <xsl:message>tan error : tan(
<xsl:value-of select=
"$x"/>) is infinite!
</xsl:message>
141 <xsl:value-of select=
"63535"/>
144 <xsl:value-of select=
" round( $cosx div $sinx * $rounding-factor) div $rounding-factor"/>
148 <xsl:template name=
"atan">
149 <xsl:param name=
"x" select=
"0"/>
150 <xsl:param name=
"rounding-factor" select=
"100"/>
152 <xsl:when test=
"$x = 0">
153 <xsl:value-of select=
"0"/>
155 <xsl:when test=
"$x < 0">
156 <xsl:variable name=
"atan-x">
157 <xsl:call-template name=
"atan">
158 <xsl:with-param name=
"x" select=
" -1 * $x"/>
159 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor"/>
162 <xsl:value-of select=
"-1 * $atan-x"/>
164 <xsl:when test=
"$x > 1">
165 <xsl:variable name=
"atan-div-x">
166 <xsl:call-template name=
"atan">
167 <xsl:with-param name=
"x" select=
"1 div $x "/>
168 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor"/>
171 <xsl:value-of select=
" $pi div 2 - $atan-div-x"/>
174 <xsl:variable name=
"arctanx">
175 <xsl:call-template name=
"atan-private">
176 <xsl:with-param name=
"x" select=
" $x "/>
179 <xsl:value-of select=
" round ( number($arctanx) * $rounding-factor ) div $rounding-factor"/>
183 <xsl:template name=
"atan2">
184 <xsl:param name=
"x"/>
185 <xsl:param name=
"y"/>
186 <xsl:param name=
"rounding-factor" select=
"100"/>
188 <xsl:when test=
"$x = 0">
189 <xsl:value-of select=
" $pi div 2"/>
192 <xsl:call-template name=
"atan">
193 <xsl:with-param name=
"x" select=
"$y div $x"/>
194 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor"/>
199 <xsl:template name=
"acos">
200 <xsl:param name=
"x"/>
201 <xsl:param name=
"rounding-factor" select=
"100"/>
202 <xsl:variable name=
"abs-x">
203 <xsl:call-template name=
"abs">
204 <xsl:with-param name=
"x" select=
"$x"/>
208 <xsl:when test=
"$abs-x > 1">
209 <xsl:message>acos error : abs(
<xsl:value-of select=
"$x"/>) greater than
1 !
</xsl:message>
212 <xsl:call-template name=
"atan2">
213 <xsl:with-param name=
"x" select=
"$x"/>
214 <xsl:with-param name=
"y">
215 <xsl:call-template name=
"sqrt">
216 <xsl:with-param name=
"x" select=
"1 - $x * $x"/>
217 <xsl:with-param name=
"rounding-factor" select=
" concat($rounding-factor,'0') "/>
224 <xsl:template name=
"asin">
225 <xsl:param name=
"x"/>
226 <xsl:param name=
"rounding-factor" select=
"100"/>
227 <xsl:variable name=
"abs-x">
228 <xsl:call-template name=
"abs">
229 <xsl:with-param name=
"x" select=
"$x"/>
233 <xsl:when test=
"$abs-x > 1">
234 <xsl:message>asin error : abs(
<xsl:value-of select=
"$x"/>) greater than
1 !
</xsl:message>
237 <xsl:call-template name=
"atan2">
238 <xsl:with-param name=
"y" select=
"$x"/>
239 <xsl:with-param name=
"x">
240 <xsl:call-template name=
"sqrt">
241 <xsl:with-param name=
"x" select=
"1 - $x * $x"/>
242 <xsl:with-param name=
"rounding-factor" select=
" concat($rounding-factor,'0') "/>
249 <xsl:template name=
"abs">
250 <xsl:param name=
"x"/>
252 <xsl:when test=
"$x > 0">
253 <xsl:value-of select=
"$x"/>
256 <xsl:value-of select=
"$x * -1"/>
260 <xsl:template name=
"max">
261 <xsl:param name=
"x1"/>
262 <xsl:param name=
"x2"/>
264 <xsl:when test=
"$x1 > $x2">
265 <xsl:value-of select=
"$x1"/>
268 <xsl:value-of select=
"$x2"/>
272 <xsl:template name=
"min">
273 <xsl:param name=
"x1"/>
274 <xsl:param name=
"x2"/>
276 <xsl:when test=
"$x1 < $x2">
277 <xsl:value-of select=
"$x1"/>
280 <xsl:value-of select=
"$x2"/>
284 <xsl:template name=
"power">
285 <xsl:param name=
"x"/>
286 <xsl:param name=
"y" select=
"1"/>
287 <xsl:param name=
"rounding-factor" select=
"100"/>
288 <!-- z is a private param -->
289 <xsl:param name=
"z" select=
"1"/>
291 <xsl:when test=
"$y > 0">
292 <xsl:call-template name=
"power">
293 <xsl:with-param name=
"x" select=
"$x"/>
294 <xsl:with-param name=
"y" select=
"$y - 1"/>
295 <xsl:with-param name=
"z" select=
"$z * $x"/>
296 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor"/>
300 <xsl:value-of select=
" round( $z * $rounding-factor) div $rounding-factor"/>
304 <xsl:template name=
"sqrt">
305 <xsl:param name=
"x"/>
306 <xsl:param name=
"rounding-factor" select=
"100"/>
308 <xsl:when test=
"$x = 0">0</xsl:when>
309 <xsl:when test=
"$x < 0">
310 <xsl:message>sqrt error :
<xsl:value-of select=
"$x"/> less than
0!
</xsl:message>
313 <xsl:call-template name=
"sqrt-private">
314 <xsl:with-param name=
"x" select=
"$x"/>
315 <xsl:with-param name=
"rounding-factor" select=
"$rounding-factor"/>
320 <!-- public functions end -->
330 <xsl:template name=
"sin-private">
331 <xsl:param name=
"x" select=
"0"/>
332 <xsl:param name=
"n" select=
"0"/>
333 <xsl:param name=
"nx" select=
"1"/>
334 <xsl:param name=
"sign" select=
"1"/>
335 <xsl:param name=
"max-n" select=
"20"/>
336 <xsl:param name=
"sinx" select=
"0"/>
338 <xsl:when test=
"not ($max-n > $n) or $nx = 0 ">
339 <xsl:value-of select=
"$sinx"/>
341 <xsl:when test=
"$n = 0">
342 <xsl:call-template name=
"sin-private">
343 <xsl:with-param name=
"x" select=
"$x"/>
344 <xsl:with-param name=
"n" select=
"$n + 1"/>
345 <xsl:with-param name=
"sign" select=
"$sign * -1"/>
346 <xsl:with-param name=
"max-n" select=
"$max-n"/>
347 <xsl:with-param name=
"nx" select=
"$x "/>
348 <xsl:with-param name=
"sinx" select=
"$sinx + $x"/>
352 <xsl:variable name=
"new-nx" select=
"($nx * $x * $x) div ( 2 * $n ) div ( 2 * $n + 1) "/>
353 <xsl:call-template name=
"sin-private">
354 <xsl:with-param name=
"x" select=
"$x"/>
355 <xsl:with-param name=
"n" select=
"$n + 1"/>
356 <xsl:with-param name=
"sign" select=
"$sign * -1"/>
357 <xsl:with-param name=
"max-n" select=
"$max-n"/>
358 <xsl:with-param name=
"nx" select=
" $new-nx "/>
359 <xsl:with-param name=
"sinx" select=
"$sinx + $new-nx * $sign"/>
364 <xsl:template name=
"cos-private">
365 <xsl:param name=
"x" select=
"0"/>
366 <xsl:param name=
"n" select=
"0"/>
367 <xsl:param name=
"nx" select=
"1"/>
368 <xsl:param name=
"sign" select=
"1"/>
369 <xsl:param name=
"max-n" select=
"20"/>
370 <xsl:param name=
"cosx" select=
"0"/>
372 <xsl:when test=
"not ($max-n > $n) or $nx = 0 ">
373 <xsl:value-of select=
"$cosx"/>
375 <xsl:when test=
"$n = 0">
376 <xsl:call-template name=
"cos-private">
377 <xsl:with-param name=
"x" select=
"$x"/>
378 <xsl:with-param name=
"n" select=
"$n + 1"/>
379 <xsl:with-param name=
"sign" select=
"$sign * -1"/>
380 <xsl:with-param name=
"max-n" select=
"$max-n"/>
381 <xsl:with-param name=
"nx" select=
" 1 "/>
382 <xsl:with-param name=
"cosx" select=
"1"/>
386 <xsl:variable name=
"new-nx" select=
"($nx * $x * $x) div ( 2 * $n -1 ) div ( 2 * $n ) "/>
387 <xsl:call-template name=
"cos-private">
388 <xsl:with-param name=
"x" select=
"$x"/>
389 <xsl:with-param name=
"n" select=
"$n + 1"/>
390 <xsl:with-param name=
"sign" select=
"$sign * -1"/>
391 <xsl:with-param name=
"max-n" select=
"$max-n"/>
392 <xsl:with-param name=
"nx" select=
" $new-nx "/>
393 <xsl:with-param name=
"cosx" select=
"$cosx + $new-nx * $sign"/>
398 <xsl:template name=
"atan-private">
399 <xsl:param name=
"x" select=
"0"/>
400 <xsl:param name=
"n" select=
"0"/>
401 <xsl:param name=
"nx" select=
"1"/>
402 <xsl:param name=
"sign" select=
"1"/>
403 <xsl:param name=
"max-n" select=
"40"/>
404 <xsl:param name=
"arctanx" select=
"0"/>
406 <xsl:when test=
"not ($max-n > $n) or $nx = 0 ">
407 <xsl:value-of select=
"$arctanx"/>
409 <xsl:when test=
"$n = 0">
410 <xsl:call-template name=
"atan-private">
411 <xsl:with-param name=
"x" select=
"$x"/>
412 <xsl:with-param name=
"n" select=
"$n + 1"/>
413 <xsl:with-param name=
"sign" select=
"$sign * -1"/>
414 <xsl:with-param name=
"max-n" select=
"$max-n"/>
415 <xsl:with-param name=
"nx" select=
"$x "/>
416 <xsl:with-param name=
"arctanx" select=
"$arctanx + $x"/>
420 <xsl:variable name=
"new-nx" select=
" $nx * $x * $x "/>
421 <xsl:call-template name=
"atan-private">
422 <xsl:with-param name=
"x" select=
"$x"/>
423 <xsl:with-param name=
"n" select=
"$n + 1"/>
424 <xsl:with-param name=
"sign" select=
"$sign * -1"/>
425 <xsl:with-param name=
"max-n" select=
"$max-n"/>
426 <xsl:with-param name=
"nx" select=
" $new-nx "/>
427 <xsl:with-param name=
"arctanx" select=
"$arctanx + $new-nx div (2 * $n +1) * $sign"/>
432 <xsl:template name=
"sqrt-private">
433 <xsl:param name=
"x"/>
434 <xsl:param name=
"rounding-factor" select=
"100"/>
435 <xsl:variable name=
"shift" select=
"string-length( $rounding-factor)"/>
436 <xsl:variable name=
"power">
437 <xsl:call-template name=
"power">
438 <xsl:with-param name=
"x" select=
"100"/>
439 <xsl:with-param name=
"y" select=
"$shift"/>
440 <xsl:with-param name=
"rounding-factor" select=
"1"/>
443 <xsl:variable name=
"integer-x" select=
" round( $power * $x )"/>
444 <xsl:variable name=
"integer-quotient">
445 <xsl:call-template name=
"integer-sqrt">
446 <xsl:with-param name=
"x" select=
"$integer-x"/>
447 <xsl:with-param name=
"length" select=
" string-length( $integer-x ) "/>
448 <xsl:with-param name=
"curr-pos" select=
" 2 - (round (string-length( $integer-x ) div 2 ) * 2 - string-length( $integer-x ) ) "/>
451 <xsl:variable name=
"power-10">
452 <xsl:call-template name=
"power">
453 <xsl:with-param name=
"x" select=
"10"/>
454 <xsl:with-param name=
"y" select=
"$shift - 1"/>
455 <xsl:with-param name=
"rounding-factor" select=
"1"/>
458 <xsl:value-of select=
" round( $integer-quotient div 10) div $power-10 "/>
460 <xsl:template name=
"integer-sqrt">
461 <xsl:param name=
"x"/>
462 <xsl:param name=
"length"/>
463 <xsl:param name=
"curr-pos"/>
464 <xsl:param name=
"last-quotient" select=
"0"/>
466 <xsl:when test=
"$curr-pos > $length">
467 <xsl:value-of select=
"$last-quotient"/>
470 <xsl:variable name=
"curr-x" select=
"substring( $x, 1, $curr-pos )"/>
471 <xsl:variable name=
"new-quotient">
472 <xsl:call-template name=
"get-one-sqrt-digit">
473 <xsl:with-param name=
"x" select=
"$curr-x"/>
474 <xsl:with-param name=
"last-quotient" select=
"$last-quotient"/>
475 <xsl:with-param name=
"n" select=
"5"/>
476 <xsl:with-param name=
"direct" select=
"0"/>
479 <xsl:call-template name=
"integer-sqrt">
480 <xsl:with-param name=
"x" select=
"$x"/>
481 <xsl:with-param name=
"length" select=
"$length"/>
482 <xsl:with-param name=
"curr-pos" select=
"$curr-pos + 2"/>
483 <xsl:with-param name=
"last-quotient" select=
"number($new-quotient)"/>
488 <xsl:template name=
"get-one-sqrt-digit">
489 <xsl:param name=
"x"/>
490 <xsl:param name=
"last-quotient"/>
491 <xsl:param name=
"n"/>
492 <xsl:param name=
"direct" select=
"1"/>
493 <xsl:variable name=
"quotient" select=
" concat( $last-quotient, $n) "/>
494 <xsl:variable name=
"accumulate" select=
"$quotient * $quotient "/>
496 <xsl:when test=
"$accumulate = $x">
497 <xsl:value-of select=
"concat($last-quotient , $n )"/>
499 <xsl:when test=
"$direct = 0 and $accumulate < $x">
500 <xsl:call-template name=
"get-one-sqrt-digit">
501 <xsl:with-param name=
"x" select=
"$x"/>
502 <xsl:with-param name=
"last-quotient" select=
"$last-quotient"/>
503 <xsl:with-param name=
"n" select=
"$n + 1"/>
504 <xsl:with-param name=
"direct" select=
"1"/>
507 <xsl:when test=
"$direct = 0 and $accumulate > $x">
508 <xsl:call-template name=
"get-one-sqrt-digit">
509 <xsl:with-param name=
"x" select=
"$x"/>
510 <xsl:with-param name=
"last-quotient" select=
"$last-quotient"/>
511 <xsl:with-param name=
"n" select=
"$n - 1"/>
512 <xsl:with-param name=
"direct" select=
"-1"/>
515 <xsl:when test=
" $accumulate * $direct < $x * $direct ">
516 <xsl:call-template name=
"get-one-sqrt-digit">
517 <xsl:with-param name=
"x" select=
"$x"/>
518 <xsl:with-param name=
"last-quotient" select=
"$last-quotient"/>
519 <xsl:with-param name=
"n" select=
"$n+ $direct"/>
520 <xsl:with-param name=
"direct" select=
"$direct"/>
523 <xsl:when test=
"not($n < 9) or $n = -1">
524 <xsl:value-of select=
"concat($last-quotient , $n - $direct) "/>
526 <xsl:when test=
"$direct = 1">
527 <xsl:value-of select=
"concat($last-quotient , $n - 1) "/>
530 <xsl:value-of select=
"concat($last-quotient , $n) "/>
534 <xsl:template name=
"convert2redian">
535 <xsl:param name=
"x" select=
"'0'"/>
536 <xsl:param name=
"rounding-factor" select=
"100"/>
538 <xsl:when test=
"contains($x,'deg')">
539 <xsl:value-of select=
"round($rounding-factor * number(substring-before($x, 'deg') div 180 * $pi)) div $rounding-factor"/>
541 <xsl:when test=
"contains($x,'fd')">
542 <xsl:value-of select=
"round($rounding-factor * number(substring-before($x, 'fd') div 180 div 65536 * $pi)) div $rounding-factor"/>
545 <xsl:value-of select=
"round($rounding-factor * number($x) div 180 * $pi) div $rounding-factor"/>
549 <xsl:template name=
"convert2degree">
550 <xsl:param name=
"x" select=
"'0'"/>
551 <xsl:param name=
"rounding-factor" select=
"100"/>
553 <xsl:when test=
"contains($x,'deg')">
554 <xsl:value-of select=
"round($rounding-factor * substring-before($x,'deg')) div $rounding-factor"/>
556 <xsl:when test=
"contains($x,'fd')">
557 <xsl:value-of select=
"round($rounding-factor * number(substring-before($x, 'fd')) div 65536 ) div $rounding-factor"/>
560 <xsl:value-of select=
"round($rounding-factor * number($x) * 180 div $pi) div $rounding-factor"/>
564 <xsl:template name=
"convert2fd">
565 <xsl:param name=
"x" select=
"'0'"/>
566 <xsl:param name=
"rounding-factor" select=
"100"/>
568 <xsl:when test=
"contains($x,'deg')">
569 <xsl:value-of select=
"round($rounding-factor * number(substring-before($x, 'deg') * 65535)) div $rounding-factor"/>
571 <xsl:when test=
"contains($x,'fd')">
572 <xsl:value-of select=
"round($rounding-factor * number(substring-before($x, 'fd'))) div $rounding-factor"/>
575 <xsl:value-of select=
"round($rounding-factor * number($x) * 180 div $pi * 65535) div $rounding-factor"/>