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"/>