1*043fbe51Sderaadt /* $OpenBSD: b_log__D.c,v 1.4 2009/10/27 23:59:29 deraadt Exp $ */
25b14c9c6Smartynas /*
35b14c9c6Smartynas * Copyright (c) 1992, 1993
45b14c9c6Smartynas * The Regents of the University of California. All rights reserved.
55b14c9c6Smartynas *
65b14c9c6Smartynas * Redistribution and use in source and binary forms, with or without
75b14c9c6Smartynas * modification, are permitted provided that the following conditions
85b14c9c6Smartynas * are met:
95b14c9c6Smartynas * 1. Redistributions of source code must retain the above copyright
105b14c9c6Smartynas * notice, this list of conditions and the following disclaimer.
115b14c9c6Smartynas * 2. Redistributions in binary form must reproduce the above copyright
125b14c9c6Smartynas * notice, this list of conditions and the following disclaimer in the
135b14c9c6Smartynas * documentation and/or other materials provided with the distribution.
145b14c9c6Smartynas * 3. Neither the name of the University nor the names of its contributors
155b14c9c6Smartynas * may be used to endorse or promote products derived from this software
165b14c9c6Smartynas * without specific prior written permission.
175b14c9c6Smartynas *
185b14c9c6Smartynas * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
195b14c9c6Smartynas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
205b14c9c6Smartynas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
215b14c9c6Smartynas * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
225b14c9c6Smartynas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
235b14c9c6Smartynas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
245b14c9c6Smartynas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
255b14c9c6Smartynas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
265b14c9c6Smartynas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
275b14c9c6Smartynas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
285b14c9c6Smartynas * SUCH DAMAGE.
295b14c9c6Smartynas */
305b14c9c6Smartynas
315b14c9c6Smartynas #include "math.h"
325b14c9c6Smartynas #include "math_private.h"
335b14c9c6Smartynas
345b14c9c6Smartynas /* Table-driven natural logarithm.
355b14c9c6Smartynas *
365b14c9c6Smartynas * This code was derived, with minor modifications, from:
375b14c9c6Smartynas * Peter Tang, "Table-Driven Implementation of the
385b14c9c6Smartynas * Logarithm in IEEE Floating-Point arithmetic." ACM Trans.
395b14c9c6Smartynas * Math Software, vol 16. no 4, pp 378-400, Dec 1990).
405b14c9c6Smartynas *
415b14c9c6Smartynas * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256,
425b14c9c6Smartynas * where F = j/128 for j an integer in [0, 128].
435b14c9c6Smartynas *
445b14c9c6Smartynas * log(2^m) = log2_hi*m + log2_tail*m
455b14c9c6Smartynas * since m is an integer, the dominant term is exact.
465b14c9c6Smartynas * m has at most 10 digits (for subnormal numbers),
475b14c9c6Smartynas * and log2_hi has 11 trailing zero bits.
485b14c9c6Smartynas *
495b14c9c6Smartynas * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h
505b14c9c6Smartynas * logF_hi[] + 512 is exact.
515b14c9c6Smartynas *
525b14c9c6Smartynas * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ...
535b14c9c6Smartynas * the leading term is calculated to extra precision in two
545b14c9c6Smartynas * parts, the larger of which adds exactly to the dominant
555b14c9c6Smartynas * m and F terms.
565b14c9c6Smartynas * There are two cases:
575b14c9c6Smartynas * 1. when m, j are non-zero (m | j), use absolute
585b14c9c6Smartynas * precision for the leading term.
595b14c9c6Smartynas * 2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1).
605b14c9c6Smartynas * In this case, use a relative precision of 24 bits.
615b14c9c6Smartynas * (This is done differently in the original paper)
625b14c9c6Smartynas *
635b14c9c6Smartynas * Special cases:
645b14c9c6Smartynas * 0 return signalling -Inf
655b14c9c6Smartynas * neg return signalling NaN
665b14c9c6Smartynas * +Inf return +Inf
675b14c9c6Smartynas */
685b14c9c6Smartynas
695b14c9c6Smartynas #define N 128
705b14c9c6Smartynas
715b14c9c6Smartynas /* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128.
725b14c9c6Smartynas * Used for generation of extend precision logarithms.
735b14c9c6Smartynas * The constant 35184372088832 is 2^45, so the divide is exact.
745b14c9c6Smartynas * It ensures correct reading of logF_head, even for inaccurate
755b14c9c6Smartynas * decimal-to-binary conversion routines. (Everybody gets the
765b14c9c6Smartynas * right answer for integers less than 2^53.)
775b14c9c6Smartynas * Values for log(F) were generated using error < 10^-57 absolute
785b14c9c6Smartynas * with the bc -l package.
795b14c9c6Smartynas */
805b14c9c6Smartynas static const double A1 = .08333333333333178827;
815b14c9c6Smartynas static const double A2 = .01250000000377174923;
825b14c9c6Smartynas static const double A3 = .002232139987919447809;
835b14c9c6Smartynas static const double A4 = .0004348877777076145742;
845b14c9c6Smartynas
855b14c9c6Smartynas static const double logF_head[N+1] = {
865b14c9c6Smartynas 0.,
875b14c9c6Smartynas .007782140442060381246,
885b14c9c6Smartynas .015504186535963526694,
895b14c9c6Smartynas .023167059281547608406,
905b14c9c6Smartynas .030771658666765233647,
915b14c9c6Smartynas .038318864302141264488,
925b14c9c6Smartynas .045809536031242714670,
935b14c9c6Smartynas .053244514518837604555,
945b14c9c6Smartynas .060624621816486978786,
955b14c9c6Smartynas .067950661908525944454,
965b14c9c6Smartynas .075223421237524235039,
975b14c9c6Smartynas .082443669210988446138,
985b14c9c6Smartynas .089612158689760690322,
995b14c9c6Smartynas .096729626458454731618,
1005b14c9c6Smartynas .103796793681567578460,
1015b14c9c6Smartynas .110814366340264314203,
1025b14c9c6Smartynas .117783035656430001836,
1035b14c9c6Smartynas .124703478501032805070,
1045b14c9c6Smartynas .131576357788617315236,
1055b14c9c6Smartynas .138402322859292326029,
1065b14c9c6Smartynas .145182009844575077295,
1075b14c9c6Smartynas .151916042025732167530,
1085b14c9c6Smartynas .158605030176659056451,
1095b14c9c6Smartynas .165249572895390883786,
1105b14c9c6Smartynas .171850256926518341060,
1115b14c9c6Smartynas .178407657472689606947,
1125b14c9c6Smartynas .184922338493834104156,
1135b14c9c6Smartynas .191394852999565046047,
1145b14c9c6Smartynas .197825743329758552135,
1155b14c9c6Smartynas .204215541428766300668,
1165b14c9c6Smartynas .210564769107350002741,
1175b14c9c6Smartynas .216873938300523150246,
1185b14c9c6Smartynas .223143551314024080056,
1195b14c9c6Smartynas .229374101064877322642,
1205b14c9c6Smartynas .235566071312860003672,
1215b14c9c6Smartynas .241719936886966024758,
1225b14c9c6Smartynas .247836163904594286577,
1235b14c9c6Smartynas .253915209980732470285,
1245b14c9c6Smartynas .259957524436686071567,
1255b14c9c6Smartynas .265963548496984003577,
1265b14c9c6Smartynas .271933715484010463114,
1275b14c9c6Smartynas .277868451003087102435,
1285b14c9c6Smartynas .283768173130738432519,
1295b14c9c6Smartynas .289633292582948342896,
1305b14c9c6Smartynas .295464212893421063199,
1315b14c9c6Smartynas .301261330578199704177,
1325b14c9c6Smartynas .307025035294827830512,
1335b14c9c6Smartynas .312755710004239517729,
1345b14c9c6Smartynas .318453731118097493890,
1355b14c9c6Smartynas .324119468654316733591,
1365b14c9c6Smartynas .329753286372579168528,
1375b14c9c6Smartynas .335355541920762334484,
1385b14c9c6Smartynas .340926586970454081892,
1395b14c9c6Smartynas .346466767346100823488,
1405b14c9c6Smartynas .351976423156884266063,
1415b14c9c6Smartynas .357455888922231679316,
1425b14c9c6Smartynas .362905493689140712376,
1435b14c9c6Smartynas .368325561158599157352,
1445b14c9c6Smartynas .373716409793814818840,
1455b14c9c6Smartynas .379078352934811846353,
1465b14c9c6Smartynas .384411698910298582632,
1475b14c9c6Smartynas .389716751140440464951,
1485b14c9c6Smartynas .394993808240542421117,
1495b14c9c6Smartynas .400243164127459749579,
1505b14c9c6Smartynas .405465108107819105498,
1515b14c9c6Smartynas .410659924985338875558,
1525b14c9c6Smartynas .415827895143593195825,
1535b14c9c6Smartynas .420969294644237379543,
1545b14c9c6Smartynas .426084395310681429691,
1555b14c9c6Smartynas .431173464818130014464,
1565b14c9c6Smartynas .436236766774527495726,
1575b14c9c6Smartynas .441274560805140936281,
1585b14c9c6Smartynas .446287102628048160113,
1595b14c9c6Smartynas .451274644139630254358,
1605b14c9c6Smartynas .456237433481874177232,
1615b14c9c6Smartynas .461175715122408291790,
1625b14c9c6Smartynas .466089729924533457960,
1635b14c9c6Smartynas .470979715219073113985,
1645b14c9c6Smartynas .475845904869856894947,
1655b14c9c6Smartynas .480688529345570714212,
1665b14c9c6Smartynas .485507815781602403149,
1675b14c9c6Smartynas .490303988045525329653,
1685b14c9c6Smartynas .495077266798034543171,
1695b14c9c6Smartynas .499827869556611403822,
1705b14c9c6Smartynas .504556010751912253908,
1715b14c9c6Smartynas .509261901790523552335,
1725b14c9c6Smartynas .513945751101346104405,
1735b14c9c6Smartynas .518607764208354637958,
1745b14c9c6Smartynas .523248143765158602036,
1755b14c9c6Smartynas .527867089620485785417,
1765b14c9c6Smartynas .532464798869114019908,
1775b14c9c6Smartynas .537041465897345915436,
1785b14c9c6Smartynas .541597282432121573947,
1795b14c9c6Smartynas .546132437597407260909,
1805b14c9c6Smartynas .550647117952394182793,
1815b14c9c6Smartynas .555141507540611200965,
1825b14c9c6Smartynas .559615787935399566777,
1835b14c9c6Smartynas .564070138285387656651,
1845b14c9c6Smartynas .568504735352689749561,
1855b14c9c6Smartynas .572919753562018740922,
1865b14c9c6Smartynas .577315365035246941260,
1875b14c9c6Smartynas .581691739635061821900,
1885b14c9c6Smartynas .586049045003164792433,
1895b14c9c6Smartynas .590387446602107957005,
1905b14c9c6Smartynas .594707107746216934174,
1915b14c9c6Smartynas .599008189645246602594,
1925b14c9c6Smartynas .603290851438941899687,
1935b14c9c6Smartynas .607555250224322662688,
1945b14c9c6Smartynas .611801541106615331955,
1955b14c9c6Smartynas .616029877215623855590,
1965b14c9c6Smartynas .620240409751204424537,
1975b14c9c6Smartynas .624433288012369303032,
1985b14c9c6Smartynas .628608659422752680256,
1995b14c9c6Smartynas .632766669570628437213,
2005b14c9c6Smartynas .636907462236194987781,
2015b14c9c6Smartynas .641031179420679109171,
2025b14c9c6Smartynas .645137961373620782978,
2035b14c9c6Smartynas .649227946625615004450,
2045b14c9c6Smartynas .653301272011958644725,
2055b14c9c6Smartynas .657358072709030238911,
2065b14c9c6Smartynas .661398482245203922502,
2075b14c9c6Smartynas .665422632544505177065,
2085b14c9c6Smartynas .669430653942981734871,
2095b14c9c6Smartynas .673422675212350441142,
2105b14c9c6Smartynas .677398823590920073911,
2115b14c9c6Smartynas .681359224807238206267,
2125b14c9c6Smartynas .685304003098281100392,
2135b14c9c6Smartynas .689233281238557538017,
2145b14c9c6Smartynas .693147180560117703862
2155b14c9c6Smartynas };
2165b14c9c6Smartynas
2175b14c9c6Smartynas static const double logF_tail[N+1] = {
2185b14c9c6Smartynas 0.,
2195b14c9c6Smartynas -.00000000000000543229938420049,
2205b14c9c6Smartynas .00000000000000172745674997061,
2215b14c9c6Smartynas -.00000000000001323017818229233,
2225b14c9c6Smartynas -.00000000000001154527628289872,
2235b14c9c6Smartynas -.00000000000000466529469958300,
2245b14c9c6Smartynas .00000000000005148849572685810,
2255b14c9c6Smartynas -.00000000000002532168943117445,
2265b14c9c6Smartynas -.00000000000005213620639136504,
2275b14c9c6Smartynas -.00000000000001819506003016881,
2285b14c9c6Smartynas .00000000000006329065958724544,
2295b14c9c6Smartynas .00000000000008614512936087814,
2305b14c9c6Smartynas -.00000000000007355770219435028,
2315b14c9c6Smartynas .00000000000009638067658552277,
2325b14c9c6Smartynas .00000000000007598636597194141,
2335b14c9c6Smartynas .00000000000002579999128306990,
2345b14c9c6Smartynas -.00000000000004654729747598444,
2355b14c9c6Smartynas -.00000000000007556920687451336,
2365b14c9c6Smartynas .00000000000010195735223708472,
2375b14c9c6Smartynas -.00000000000017319034406422306,
2385b14c9c6Smartynas -.00000000000007718001336828098,
2395b14c9c6Smartynas .00000000000010980754099855238,
2405b14c9c6Smartynas -.00000000000002047235780046195,
2415b14c9c6Smartynas -.00000000000008372091099235912,
2425b14c9c6Smartynas .00000000000014088127937111135,
2435b14c9c6Smartynas .00000000000012869017157588257,
2445b14c9c6Smartynas .00000000000017788850778198106,
2455b14c9c6Smartynas .00000000000006440856150696891,
2465b14c9c6Smartynas .00000000000016132822667240822,
2475b14c9c6Smartynas -.00000000000007540916511956188,
2485b14c9c6Smartynas -.00000000000000036507188831790,
2495b14c9c6Smartynas .00000000000009120937249914984,
2505b14c9c6Smartynas .00000000000018567570959796010,
2515b14c9c6Smartynas -.00000000000003149265065191483,
2525b14c9c6Smartynas -.00000000000009309459495196889,
2535b14c9c6Smartynas .00000000000017914338601329117,
2545b14c9c6Smartynas -.00000000000001302979717330866,
2555b14c9c6Smartynas .00000000000023097385217586939,
2565b14c9c6Smartynas .00000000000023999540484211737,
2575b14c9c6Smartynas .00000000000015393776174455408,
2585b14c9c6Smartynas -.00000000000036870428315837678,
2595b14c9c6Smartynas .00000000000036920375082080089,
2605b14c9c6Smartynas -.00000000000009383417223663699,
2615b14c9c6Smartynas .00000000000009433398189512690,
2625b14c9c6Smartynas .00000000000041481318704258568,
2635b14c9c6Smartynas -.00000000000003792316480209314,
2645b14c9c6Smartynas .00000000000008403156304792424,
2655b14c9c6Smartynas -.00000000000034262934348285429,
2665b14c9c6Smartynas .00000000000043712191957429145,
2675b14c9c6Smartynas -.00000000000010475750058776541,
2685b14c9c6Smartynas -.00000000000011118671389559323,
2695b14c9c6Smartynas .00000000000037549577257259853,
2705b14c9c6Smartynas .00000000000013912841212197565,
2715b14c9c6Smartynas .00000000000010775743037572640,
2725b14c9c6Smartynas .00000000000029391859187648000,
2735b14c9c6Smartynas -.00000000000042790509060060774,
2745b14c9c6Smartynas .00000000000022774076114039555,
2755b14c9c6Smartynas .00000000000010849569622967912,
2765b14c9c6Smartynas -.00000000000023073801945705758,
2775b14c9c6Smartynas .00000000000015761203773969435,
2785b14c9c6Smartynas .00000000000003345710269544082,
2795b14c9c6Smartynas -.00000000000041525158063436123,
2805b14c9c6Smartynas .00000000000032655698896907146,
2815b14c9c6Smartynas -.00000000000044704265010452446,
2825b14c9c6Smartynas .00000000000034527647952039772,
2835b14c9c6Smartynas -.00000000000007048962392109746,
2845b14c9c6Smartynas .00000000000011776978751369214,
2855b14c9c6Smartynas -.00000000000010774341461609578,
2865b14c9c6Smartynas .00000000000021863343293215910,
2875b14c9c6Smartynas .00000000000024132639491333131,
2885b14c9c6Smartynas .00000000000039057462209830700,
2895b14c9c6Smartynas -.00000000000026570679203560751,
2905b14c9c6Smartynas .00000000000037135141919592021,
2915b14c9c6Smartynas -.00000000000017166921336082431,
2925b14c9c6Smartynas -.00000000000028658285157914353,
2935b14c9c6Smartynas -.00000000000023812542263446809,
2945b14c9c6Smartynas .00000000000006576659768580062,
2955b14c9c6Smartynas -.00000000000028210143846181267,
2965b14c9c6Smartynas .00000000000010701931762114254,
2975b14c9c6Smartynas .00000000000018119346366441110,
2985b14c9c6Smartynas .00000000000009840465278232627,
2995b14c9c6Smartynas -.00000000000033149150282752542,
3005b14c9c6Smartynas -.00000000000018302857356041668,
3015b14c9c6Smartynas -.00000000000016207400156744949,
3025b14c9c6Smartynas .00000000000048303314949553201,
3035b14c9c6Smartynas -.00000000000071560553172382115,
3045b14c9c6Smartynas .00000000000088821239518571855,
3055b14c9c6Smartynas -.00000000000030900580513238244,
3065b14c9c6Smartynas -.00000000000061076551972851496,
3075b14c9c6Smartynas .00000000000035659969663347830,
3085b14c9c6Smartynas .00000000000035782396591276383,
3095b14c9c6Smartynas -.00000000000046226087001544578,
3105b14c9c6Smartynas .00000000000062279762917225156,
3115b14c9c6Smartynas .00000000000072838947272065741,
3125b14c9c6Smartynas .00000000000026809646615211673,
3135b14c9c6Smartynas -.00000000000010960825046059278,
3145b14c9c6Smartynas .00000000000002311949383800537,
3155b14c9c6Smartynas -.00000000000058469058005299247,
3165b14c9c6Smartynas -.00000000000002103748251144494,
3175b14c9c6Smartynas -.00000000000023323182945587408,
3185b14c9c6Smartynas -.00000000000042333694288141916,
3195b14c9c6Smartynas -.00000000000043933937969737844,
3205b14c9c6Smartynas .00000000000041341647073835565,
3215b14c9c6Smartynas .00000000000006841763641591466,
3225b14c9c6Smartynas .00000000000047585534004430641,
3235b14c9c6Smartynas .00000000000083679678674757695,
3245b14c9c6Smartynas -.00000000000085763734646658640,
3255b14c9c6Smartynas .00000000000021913281229340092,
3265b14c9c6Smartynas -.00000000000062242842536431148,
3275b14c9c6Smartynas -.00000000000010983594325438430,
3285b14c9c6Smartynas .00000000000065310431377633651,
3295b14c9c6Smartynas -.00000000000047580199021710769,
3305b14c9c6Smartynas -.00000000000037854251265457040,
3315b14c9c6Smartynas .00000000000040939233218678664,
3325b14c9c6Smartynas .00000000000087424383914858291,
3335b14c9c6Smartynas .00000000000025218188456842882,
3345b14c9c6Smartynas -.00000000000003608131360422557,
3355b14c9c6Smartynas -.00000000000050518555924280902,
3365b14c9c6Smartynas .00000000000078699403323355317,
3375b14c9c6Smartynas -.00000000000067020876961949060,
3385b14c9c6Smartynas .00000000000016108575753932458,
3395b14c9c6Smartynas .00000000000058527188436251509,
3405b14c9c6Smartynas -.00000000000035246757297904791,
3415b14c9c6Smartynas -.00000000000018372084495629058,
3425b14c9c6Smartynas .00000000000088606689813494916,
3435b14c9c6Smartynas .00000000000066486268071468700,
3445b14c9c6Smartynas .00000000000063831615170646519,
3455b14c9c6Smartynas .00000000000025144230728376072,
3465b14c9c6Smartynas -.00000000000017239444525614834
3475b14c9c6Smartynas };
3485b14c9c6Smartynas
3495b14c9c6Smartynas /*
3505b14c9c6Smartynas * Extra precision variant, returning struct {double a, b;};
3515b14c9c6Smartynas * log(x) = a+b to 63 bits, with a rounded to 26 bits.
3525b14c9c6Smartynas */
3535b14c9c6Smartynas struct Double
__log__D(double x)3545b14c9c6Smartynas __log__D(double x)
3555b14c9c6Smartynas {
3565b14c9c6Smartynas int m, j;
3575b14c9c6Smartynas double F, f, g, q, u, v, u2;
3585b14c9c6Smartynas volatile double u1;
3595b14c9c6Smartynas struct Double r;
3605b14c9c6Smartynas
3615b14c9c6Smartynas /* Argument reduction: 1 <= g < 2; x/2^m = g; */
3625b14c9c6Smartynas /* y = F*(1 + f/F) for |f| <= 2^-8 */
3635b14c9c6Smartynas
3645b14c9c6Smartynas m = logb(x);
3655b14c9c6Smartynas g = ldexp(x, -m);
3665b14c9c6Smartynas if (m == -1022) {
36704bb2d53Smartynas j = logb(g);
36804bb2d53Smartynas m += j;
3695b14c9c6Smartynas g = ldexp(g, -j);
3705b14c9c6Smartynas }
3715b14c9c6Smartynas j = N*(g-1) + .5;
3725b14c9c6Smartynas F = (1.0/N) * j + 1;
3735b14c9c6Smartynas f = g - F;
3745b14c9c6Smartynas
3755b14c9c6Smartynas g = 1/(2*F+f);
3765b14c9c6Smartynas u = 2*f*g;
3775b14c9c6Smartynas v = u*u;
3785b14c9c6Smartynas q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
37904bb2d53Smartynas if (m | j) {
38004bb2d53Smartynas u1 = u + 513;
38104bb2d53Smartynas u1 -= 513;
38204bb2d53Smartynas }
3835173bed6Smartynas else {
3845173bed6Smartynas u1 = u;
3855173bed6Smartynas TRUNC(u1);
3865173bed6Smartynas }
3875b14c9c6Smartynas u2 = (2.0*(f - F*u1) - u1*f) * g;
3885b14c9c6Smartynas
3895b14c9c6Smartynas u1 += m*logF_head[N] + logF_head[j];
3905b14c9c6Smartynas
3915b14c9c6Smartynas u2 += logF_tail[j]; u2 += q;
3925b14c9c6Smartynas u2 += logF_tail[N]*m;
3935b14c9c6Smartynas r.a = u1 + u2; /* Only difference is here */
3945b14c9c6Smartynas TRUNC(r.a);
3955b14c9c6Smartynas r.b = (u1 - r.a) + u2;
3965b14c9c6Smartynas return (r);
3975b14c9c6Smartynas }
398