numbers.c 116 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722
  1. /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2005, 2006
  2. * Free Software Foundation, Inc.
  3. *
  4. * Portions Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories
  5. * and Bellcore. See scm_divide.
  6. *
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2, or (at your option)
  11. * any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this software; see the file COPYING. If not, write to
  20. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  21. * Boston, MA 02110-1301 USA
  22. *
  23. * As a special exception, the Free Software Foundation gives permission
  24. * for additional uses of the text contained in its release of GUILE.
  25. *
  26. * The exception is that, if you link the GUILE library with other files
  27. * to produce an executable, this does not by itself cause the
  28. * resulting executable to be covered by the GNU General Public License.
  29. * Your use of that executable is in no way restricted on account of
  30. * linking the GUILE library code into it.
  31. *
  32. * This exception does not however invalidate any other reasons why
  33. * the executable file might be covered by the GNU General Public License.
  34. *
  35. * This exception applies only to the code released by the
  36. * Free Software Foundation under the name GUILE. If you copy
  37. * code from other Free Software Foundation releases into a copy of
  38. * GUILE, as the General Public License permits, the exception does
  39. * not apply to the code that you add in this way. To avoid misleading
  40. * anyone as to the status of such modified files, you must delete
  41. * this exception notice from them.
  42. *
  43. * If you write modifications of your own for GUILE, it is your choice
  44. * whether to permit this exception to apply to your modifications.
  45. * If you do not wish that, delete this exception notice. */
  46. #include <math.h>
  47. #include "libguile/_scm.h"
  48. #include "libguile/feature.h"
  49. #include "libguile/ports.h"
  50. #include "libguile/root.h"
  51. #include "libguile/smob.h"
  52. #include "libguile/strings.h"
  53. #include "libguile/validate.h"
  54. #include "libguile/numbers.h"
  55. #include "libguile/deprecation.h"
  56. static SCM scm_divbigbig (SCM_BIGDIG *x, size_t nx, SCM_BIGDIG *y, size_t ny, int sgn, int modes);
  57. static SCM scm_divbigint (SCM x, long z, int sgn, int mode);
  58. #define DIGITS '0':case '1':case '2':case '3':case '4':\
  59. case '5':case '6':case '7':case '8':case '9'
  60. #define SCM_SWAP(x,y) do { SCM __t = x; x = y; y = __t; } while (0)
  61. /* FLOBUFLEN is the maximum number of characters neccessary for the
  62. * printed or scm_string representation of an inexact number.
  63. */
  64. #define FLOBUFLEN (10+2*(sizeof(double)/sizeof(char)*SCM_CHAR_BIT*3+9)/10)
  65. /* IS_INF tests its floating point number for infiniteness
  66. Dirk:FIXME:: This test does not work if x == 0
  67. */
  68. #ifndef IS_INF
  69. #define IS_INF(x) ((x) == (x) / 2)
  70. #endif
  71. /* Return true if X is not infinite and is not a NaN
  72. Dirk:FIXME:: Since IS_INF is broken, this test does not work if x == 0
  73. */
  74. #ifndef isfinite
  75. #define isfinite(x) (!IS_INF (x) && (x) == (x))
  76. #endif
  77. static SCM abs_most_negative_fixnum;
  78. SCM_DEFINE (scm_exact_p, "exact?", 1, 0, 0,
  79. (SCM x),
  80. "Return @code{#t} if @var{x} is an exact number, @code{#f}\n"
  81. "otherwise.")
  82. #define FUNC_NAME s_scm_exact_p
  83. {
  84. if (SCM_INUMP (x)) {
  85. return SCM_BOOL_T;
  86. } else if (SCM_BIGP (x)) {
  87. return SCM_BOOL_T;
  88. } else {
  89. return SCM_BOOL_F;
  90. }
  91. }
  92. #undef FUNC_NAME
  93. SCM_DEFINE (scm_odd_p, "odd?", 1, 0, 0,
  94. (SCM n),
  95. "Return @code{#t} if @var{n} is an odd number, @code{#f}\n"
  96. "otherwise.")
  97. #define FUNC_NAME s_scm_odd_p
  98. {
  99. if (SCM_INUMP (n)) {
  100. return SCM_BOOL ((4 & SCM_UNPACK (n)) != 0);
  101. } else if (SCM_BIGP (n)) {
  102. return SCM_BOOL ((1 & SCM_BDIGITS (n) [0]) != 0);
  103. } else {
  104. SCM_WRONG_TYPE_ARG (1, n);
  105. }
  106. }
  107. #undef FUNC_NAME
  108. SCM_DEFINE (scm_even_p, "even?", 1, 0, 0,
  109. (SCM n),
  110. "Return @code{#t} if @var{n} is an even number, @code{#f}\n"
  111. "otherwise.")
  112. #define FUNC_NAME s_scm_even_p
  113. {
  114. if (SCM_INUMP (n)) {
  115. return SCM_BOOL ((4 & SCM_UNPACK (n)) == 0);
  116. } else if (SCM_BIGP (n)) {
  117. return SCM_BOOL ((1 & SCM_BDIGITS (n) [0]) == 0);
  118. } else {
  119. SCM_WRONG_TYPE_ARG (1, n);
  120. }
  121. }
  122. #undef FUNC_NAME
  123. SCM_GPROC (s_abs, "abs", 1, 0, 0, scm_abs, g_abs);
  124. /* "Return the absolute value of @var{x}."
  125. */
  126. SCM
  127. scm_abs (SCM x)
  128. {
  129. if (SCM_INUMP (x)) {
  130. long int xx = SCM_INUM (x);
  131. if (xx >= 0) {
  132. return x;
  133. } else if (SCM_POSFIXABLE (-xx)) {
  134. return SCM_MAKINUM (-xx);
  135. } else {
  136. #ifdef SCM_BIGDIG
  137. return scm_i_long2big (-xx);
  138. #else
  139. scm_num_overflow (s_abs);
  140. #endif
  141. }
  142. } else if (SCM_BIGP (x)) {
  143. if (!SCM_BIGSIGN (x)) {
  144. return x;
  145. } else {
  146. return scm_i_copybig (x, 0);
  147. }
  148. } else if (SCM_REALP (x)) {
  149. return scm_make_real (fabs (SCM_REAL_VALUE (x)));
  150. } else {
  151. SCM_WTA_DISPATCH_1 (g_abs, x, 1, s_abs);
  152. }
  153. }
  154. SCM_GPROC (s_quotient, "quotient", 2, 0, 0, scm_quotient, g_quotient);
  155. /* "Return the quotient of the numbers @var{x} and @var{y}."
  156. */
  157. SCM
  158. scm_quotient (SCM x, SCM y)
  159. {
  160. if (SCM_INUMP (x)) {
  161. long xx = SCM_INUM (x);
  162. if (SCM_INUMP (y)) {
  163. long yy = SCM_INUM (y);
  164. if (yy == 0) {
  165. scm_num_overflow (s_quotient);
  166. } else {
  167. long z = xx / yy;
  168. if (SCM_FIXABLE (z)) {
  169. return SCM_MAKINUM (z);
  170. } else {
  171. #ifdef SCM_BIGDIG
  172. return scm_i_long2big (z);
  173. #else
  174. scm_num_overflow (s_quotient);
  175. #endif
  176. }
  177. }
  178. } else if (SCM_BIGP (y)) {
  179. if (SCM_INUM (x) == SCM_MOST_NEGATIVE_FIXNUM
  180. && scm_bigcomp (abs_most_negative_fixnum, y) == 0)
  181. {
  182. /* Special case: x == fixnum-min && y == abs (fixnum-min) */
  183. return SCM_MAKINUM (-1);
  184. }
  185. else
  186. return SCM_MAKINUM (0);
  187. } else {
  188. SCM_WTA_DISPATCH_2 (g_quotient, x, y, SCM_ARG2, s_quotient);
  189. }
  190. } else if (SCM_BIGP (x)) {
  191. if (SCM_INUMP (y)) {
  192. long yy = SCM_INUM (y);
  193. if (yy == 0) {
  194. scm_num_overflow (s_quotient);
  195. } else if (yy == 1) {
  196. return x;
  197. } else {
  198. long z = yy < 0 ? -yy : yy;
  199. if (z < SCM_BIGRAD) {
  200. SCM sw = scm_i_copybig (x, SCM_BIGSIGN (x) ? (yy > 0) : (yy < 0));
  201. scm_divbigdig (SCM_BDIGITS (sw), SCM_NUMDIGS (sw), (SCM_BIGDIG) z);
  202. return scm_i_normbig (sw);
  203. } else {
  204. #ifndef SCM_DIGSTOOBIG
  205. long w = scm_pseudolong (z);
  206. return scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
  207. (SCM_BIGDIG *) & w, SCM_DIGSPERLONG,
  208. SCM_BIGSIGN (x) ? (yy > 0) : (yy < 0), 2);
  209. #else
  210. SCM_BIGDIG zdigs[SCM_DIGSPERLONG];
  211. scm_longdigs (z, zdigs);
  212. return scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
  213. zdigs, SCM_DIGSPERLONG,
  214. SCM_BIGSIGN (x) ? (yy > 0) : (yy < 0), 2);
  215. #endif
  216. }
  217. }
  218. } else if (SCM_BIGP (y)) {
  219. return scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
  220. SCM_BDIGITS (y), SCM_NUMDIGS (y),
  221. SCM_BIGSIGN (x) ^ SCM_BIGSIGN (y), 2);
  222. } else {
  223. SCM_WTA_DISPATCH_2 (g_quotient, x, y, SCM_ARG2, s_quotient);
  224. }
  225. } else {
  226. SCM_WTA_DISPATCH_2 (g_quotient, x, y, SCM_ARG1, s_quotient);
  227. }
  228. }
  229. SCM_GPROC (s_remainder, "remainder", 2, 0, 0, scm_remainder, g_remainder);
  230. /* "Return the remainder of the numbers @var{x} and @var{y}.\n"
  231. * "@lisp\n"
  232. * "(remainder 13 4) @result{} 1\n"
  233. * "(remainder -13 4) @result{} -1\n"
  234. * "@end lisp"
  235. */
  236. SCM
  237. scm_remainder (SCM x, SCM y)
  238. {
  239. if (SCM_INUMP (x)) {
  240. if (SCM_INUMP (y)) {
  241. long yy = SCM_INUM (y);
  242. if (yy == 0) {
  243. scm_num_overflow (s_remainder);
  244. } else {
  245. long z = SCM_INUM (x) % yy;
  246. return SCM_MAKINUM (z);
  247. }
  248. } else if (SCM_BIGP (y)) {
  249. if (SCM_INUM (x) == SCM_MOST_NEGATIVE_FIXNUM
  250. && scm_bigcomp (abs_most_negative_fixnum, y) == 0)
  251. {
  252. /* Special case: x == fixnum-min && y == abs (fixnum-min) */
  253. return SCM_MAKINUM (0);
  254. }
  255. else
  256. return x;
  257. } else {
  258. SCM_WTA_DISPATCH_2 (g_remainder, x, y, SCM_ARG2, s_remainder);
  259. }
  260. } else if (SCM_BIGP (x)) {
  261. if (SCM_INUMP (y)) {
  262. long yy = SCM_INUM (y);
  263. if (yy == 0) {
  264. scm_num_overflow (s_remainder);
  265. } else {
  266. return scm_divbigint (x, yy, SCM_BIGSIGN (x), 0);
  267. }
  268. } else if (SCM_BIGP (y)) {
  269. return scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
  270. SCM_BDIGITS (y), SCM_NUMDIGS (y),
  271. SCM_BIGSIGN (x), 0);
  272. } else {
  273. SCM_WTA_DISPATCH_2 (g_remainder, x, y, SCM_ARG2, s_remainder);
  274. }
  275. } else {
  276. SCM_WTA_DISPATCH_2 (g_remainder, x, y, SCM_ARG1, s_remainder);
  277. }
  278. }
  279. SCM_GPROC (s_modulo, "modulo", 2, 0, 0, scm_modulo, g_modulo);
  280. /* "Return the modulo of the numbers @var{x} and @var{y}.\n"
  281. * "@lisp\n"
  282. * "(modulo 13 4) @result{} 1\n"
  283. * "(modulo -13 4) @result{} 3\n"
  284. * "@end lisp"
  285. */
  286. SCM
  287. scm_modulo (SCM x, SCM y)
  288. {
  289. if (SCM_INUMP (x)) {
  290. long xx = SCM_INUM (x);
  291. if (SCM_INUMP (y)) {
  292. long yy = SCM_INUM (y);
  293. if (yy == 0) {
  294. scm_num_overflow (s_modulo);
  295. } else {
  296. long z = xx % yy;
  297. return SCM_MAKINUM (((yy < 0) ? (z > 0) : (z < 0)) ? z + yy : z);
  298. }
  299. } else if (SCM_BIGP (y)) {
  300. return (SCM_BIGSIGN (y) ? (xx > 0) : (xx < 0)) ? scm_sum (x, y) : x;
  301. } else {
  302. SCM_WTA_DISPATCH_2 (g_modulo, x, y, SCM_ARG2, s_modulo);
  303. }
  304. } else if (SCM_BIGP (x)) {
  305. if (SCM_INUMP (y)) {
  306. long yy = SCM_INUM (y);
  307. if (yy == 0) {
  308. scm_num_overflow (s_modulo);
  309. } else {
  310. return scm_divbigint (x, yy, yy < 0,
  311. (SCM_BIGSIGN (x) ? (yy > 0) : (yy < 0)) ? 1 : 0);
  312. }
  313. } else if (SCM_BIGP (y)) {
  314. return scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
  315. SCM_BDIGITS (y), SCM_NUMDIGS (y),
  316. SCM_BIGSIGN (y),
  317. (SCM_BIGSIGN (x) ^ SCM_BIGSIGN (y)) ? 1 : 0);
  318. } else {
  319. SCM_WTA_DISPATCH_2 (g_modulo, x, y, SCM_ARG2, s_modulo);
  320. }
  321. } else {
  322. SCM_WTA_DISPATCH_2 (g_modulo, x, y, SCM_ARG1, s_modulo);
  323. }
  324. }
  325. SCM_GPROC1 (s_gcd, "gcd", scm_tc7_asubr, scm_gcd, g_gcd);
  326. /* "Return the greatest common divisor of all arguments.\n"
  327. * "If called without arguments, 0 is returned."
  328. */
  329. SCM
  330. scm_gcd (SCM x, SCM y)
  331. {
  332. if (SCM_UNBNDP (y)) {
  333. if (SCM_UNBNDP (x)) {
  334. return SCM_INUM0;
  335. } else {
  336. return x;
  337. }
  338. }
  339. tailrec:
  340. if (SCM_INUMP (x)) {
  341. if (SCM_INUMP (y)) {
  342. long xx = SCM_INUM (x);
  343. long yy = SCM_INUM (y);
  344. long u = xx < 0 ? -xx : xx;
  345. long v = yy < 0 ? -yy : yy;
  346. long result;
  347. if (xx == 0) {
  348. result = v;
  349. } else if (yy == 0) {
  350. result = u;
  351. } else {
  352. long k = 1;
  353. long t;
  354. /* Determine a common factor 2^k */
  355. while (!(1 & (u | v))) {
  356. k <<= 1;
  357. u >>= 1;
  358. v >>= 1;
  359. }
  360. /* Now, any factor 2^n can be eliminated */
  361. if (u & 1) {
  362. t = -v;
  363. } else {
  364. t = u;
  365. b3:
  366. t = SCM_SRS (t, 1);
  367. }
  368. if (!(1 & t))
  369. goto b3;
  370. if (t > 0)
  371. u = t;
  372. else
  373. v = -t;
  374. t = u - v;
  375. if (t != 0)
  376. goto b3;
  377. result = u * k;
  378. }
  379. if (SCM_POSFIXABLE (result)) {
  380. return SCM_MAKINUM (result);
  381. } else {
  382. #ifdef SCM_BIGDIG
  383. return scm_i_long2big (result);
  384. #else
  385. scm_num_overflow (s_gcd);
  386. #endif
  387. }
  388. } else if (SCM_BIGP (y)) {
  389. SCM_SWAP (x, y);
  390. goto big_gcd;
  391. } else {
  392. SCM_WTA_DISPATCH_2 (g_gcd, x, y, SCM_ARG2, s_gcd);
  393. }
  394. } else if (SCM_BIGP (x)) {
  395. big_gcd:
  396. if (SCM_BIGSIGN (x))
  397. x = scm_i_copybig (x, 0);
  398. newy:
  399. if (SCM_INUMP (y)) {
  400. if (SCM_EQ_P (y, SCM_INUM0)) {
  401. return x;
  402. } else {
  403. goto swaprec;
  404. }
  405. } else if (SCM_BIGP (y)) {
  406. if (SCM_BIGSIGN (y))
  407. y = scm_i_copybig (y, 0);
  408. switch (scm_bigcomp (x, y))
  409. {
  410. case -1: /* x > y */
  411. swaprec:
  412. {
  413. SCM t = scm_remainder (x, y);
  414. x = y;
  415. y = t;
  416. }
  417. goto tailrec;
  418. case 1: /* x < y */
  419. y = scm_remainder (y, x);
  420. goto newy;
  421. default: /* x == y */
  422. return x;
  423. }
  424. /* instead of the switch, we could just
  425. return scm_gcd (y, scm_modulo (x, y)); */
  426. } else {
  427. SCM_WTA_DISPATCH_2 (g_gcd, x, y, SCM_ARG2, s_gcd);
  428. }
  429. } else {
  430. SCM_WTA_DISPATCH_2 (g_gcd, x, y, SCM_ARG1, s_gcd);
  431. }
  432. }
  433. SCM_GPROC1 (s_lcm, "lcm", scm_tc7_asubr, scm_lcm, g_lcm);
  434. /* "Return the least common multiple of the arguments.\n"
  435. * "If called without arguments, 1 is returned."
  436. */
  437. SCM
  438. scm_lcm (SCM n1, SCM n2)
  439. {
  440. if (SCM_UNBNDP (n2)) {
  441. if (SCM_UNBNDP (n1)) {
  442. return SCM_MAKINUM (1L);
  443. } else {
  444. n2 = SCM_MAKINUM (1L);
  445. }
  446. };
  447. #ifndef SCM_BIGDIG
  448. SCM_GASSERT2 (SCM_INUMP (n1), g_lcm, n1, n2, SCM_ARG1, s_lcm);
  449. SCM_GASSERT2 (SCM_INUMP (n2), g_lcm, n1, n2, SCM_ARGn, s_lcm);
  450. #else
  451. SCM_GASSERT2 (SCM_INUMP (n1) || SCM_BIGP (n1),
  452. g_lcm, n1, n2, SCM_ARG1, s_lcm);
  453. SCM_GASSERT2 (SCM_INUMP (n2) || SCM_BIGP (n2),
  454. g_lcm, n1, n2, SCM_ARGn, s_lcm);
  455. #endif
  456. {
  457. SCM d = scm_gcd (n1, n2);
  458. if (SCM_EQ_P (d, SCM_INUM0)) {
  459. return d;
  460. } else {
  461. return scm_abs (scm_product (n1, scm_quotient (n2, d)));
  462. }
  463. }
  464. }
  465. #ifndef scm_long2num
  466. #define SCM_LOGOP_RETURN(x) scm_ulong2num(x)
  467. #else
  468. #define SCM_LOGOP_RETURN(x) SCM_MAKINUM(x)
  469. #endif
  470. /* Emulating 2's complement bignums with sign magnitude arithmetic:
  471. Logand:
  472. X Y Result Method:
  473. (len)
  474. + + + x (map digit:logand X Y)
  475. + - + x (map digit:logand X (lognot (+ -1 Y)))
  476. - + + y (map digit:logand (lognot (+ -1 X)) Y)
  477. - - - (+ 1 (map digit:logior (+ -1 X) (+ -1 Y)))
  478. Logior:
  479. X Y Result Method:
  480. + + + (map digit:logior X Y)
  481. + - - y (+ 1 (map digit:logand (lognot X) (+ -1 Y)))
  482. - + - x (+ 1 (map digit:logand (+ -1 X) (lognot Y)))
  483. - - - x (+ 1 (map digit:logand (+ -1 X) (+ -1 Y)))
  484. Logxor:
  485. X Y Result Method:
  486. + + + (map digit:logxor X Y)
  487. + - - (+ 1 (map digit:logxor X (+ -1 Y)))
  488. - + - (+ 1 (map digit:logxor (+ -1 X) Y))
  489. - - + (map digit:logxor (+ -1 X) (+ -1 Y))
  490. Logtest:
  491. X Y Result
  492. + + (any digit:logand X Y)
  493. + - (any digit:logand X (lognot (+ -1 Y)))
  494. - + (any digit:logand (lognot (+ -1 X)) Y)
  495. - - #t
  496. */
  497. #ifdef SCM_BIGDIG
  498. SCM scm_copy_big_dec(SCM b, int sign);
  499. SCM scm_copy_smaller(SCM_BIGDIG *x, size_t nx, int zsgn);
  500. SCM scm_big_ior(SCM_BIGDIG *x, size_t nx, int xsgn, SCM bigy);
  501. SCM scm_big_xor(SCM_BIGDIG *x, size_t nx, int xsgn, SCM bigy);
  502. SCM scm_big_and(SCM_BIGDIG *x, size_t nx, int xsgn, SCM bigy, int zsgn);
  503. SCM scm_big_test(SCM_BIGDIG *x, size_t nx, int xsgn, SCM bigy);
  504. SCM scm_copy_big_dec(SCM b, int sign)
  505. {
  506. long num = -1;
  507. size_t nx = SCM_NUMDIGS(b);
  508. size_t i = 0;
  509. SCM ans = scm_i_mkbig(nx, sign);
  510. SCM_BIGDIG *src = SCM_BDIGITS(b), *dst = SCM_BDIGITS(ans);
  511. if SCM_BIGSIGN(b) do {
  512. num += src[i];
  513. if (num < 0) {dst[i] = num + SCM_BIGRAD; num = -1;}
  514. else {dst[i] = SCM_BIGLO(num); num = 0;}
  515. } while (++i < nx);
  516. else
  517. while (nx--) dst[nx] = src[nx];
  518. return ans;
  519. }
  520. SCM scm_copy_smaller(SCM_BIGDIG *x, size_t nx, int zsgn)
  521. {
  522. long num = -1;
  523. size_t i = 0;
  524. SCM z = scm_i_mkbig(nx, zsgn);
  525. SCM_BIGDIG *zds = SCM_BDIGITS(z);
  526. if (zsgn) do {
  527. num += x[i];
  528. if (num < 0) {zds[i] = num + SCM_BIGRAD; num = -1;}
  529. else {zds[i] = SCM_BIGLO(num); num = 0;}
  530. } while (++i < nx);
  531. else do zds[i] = x[i]; while (++i < nx);
  532. return z;
  533. }
  534. SCM scm_big_ior(SCM_BIGDIG *x, size_t nx, int xsgn, SCM bigy)
  535. /* Assumes nx <= SCM_NUMDIGS(bigy) */
  536. /* Assumes xsgn equals either 0 or SCM_BIGSIGNFLAG */
  537. {
  538. long num = -1;
  539. size_t i = 0, ny = SCM_NUMDIGS(bigy);
  540. SCM z = scm_copy_big_dec (bigy, xsgn & SCM_BIGSIGN (bigy));
  541. SCM_BIGDIG *zds = SCM_BDIGITS(z);
  542. if (xsgn) {
  543. do {
  544. num += x[i];
  545. if (num < 0) {zds[i] |= num + SCM_BIGRAD; num = -1;}
  546. else {zds[i] |= SCM_BIGLO(num); num = 0;}
  547. } while (++i < nx);
  548. /* ========= Need to increment zds now =========== */
  549. i = 0; num = 1;
  550. while (i < ny) {
  551. num += zds[i];
  552. zds[i++] = SCM_BIGLO(num);
  553. num = SCM_BIGDN(num);
  554. if (!num) return z;
  555. }
  556. scm_i_adjbig(z, 1 + ny); /* OOPS, overflowed into next digit. */
  557. SCM_BDIGITS(z)[ny] = 1;
  558. return z;
  559. }
  560. else do zds[i] = zds[i] | x[i]; while (++i < nx);
  561. return z;
  562. }
  563. SCM scm_big_xor(SCM_BIGDIG *x, size_t nx, int xsgn, SCM bigy)
  564. /* Assumes nx <= SCM_NUMDIGS(bigy) */
  565. /* Assumes xsgn equals either 0 or SCM_BIGSIGNFLAG */
  566. {
  567. long num = -1;
  568. size_t i = 0, ny = SCM_NUMDIGS(bigy);
  569. SCM z = scm_copy_big_dec(bigy, xsgn ^ SCM_BIGSIGN(bigy));
  570. SCM_BIGDIG *zds = SCM_BDIGITS(z);
  571. if (xsgn) do {
  572. num += x[i];
  573. if (num < 0) {zds[i] ^= num + SCM_BIGRAD; num = -1;}
  574. else {zds[i] ^= SCM_BIGLO(num); num = 0;}
  575. } while (++i < nx);
  576. else do {
  577. zds[i] = zds[i] ^ x[i];
  578. } while (++i < nx);
  579. if (xsgn ^ SCM_BIGSIGN(bigy)) {
  580. /* ========= Need to increment zds now =========== */
  581. i = 0; num = 1;
  582. while (i < ny) {
  583. num += zds[i];
  584. zds[i++] = SCM_BIGLO(num);
  585. num = SCM_BIGDN(num);
  586. if (!num) return scm_i_normbig(z);
  587. }
  588. }
  589. return scm_i_normbig(z);
  590. }
  591. SCM scm_big_and(SCM_BIGDIG *x, size_t nx, int xsgn, SCM bigy, int zsgn)
  592. /* Assumes nx <= SCM_NUMDIGS(bigy) */
  593. /* Assumes xsgn equals either 0 or SCM_BIGSIGNFLAG */
  594. /* return sign equals either 0 or SCM_BIGSIGNFLAG */
  595. {
  596. long num = -1;
  597. size_t i = 0;
  598. SCM z;
  599. SCM_BIGDIG *zds;
  600. if (xsgn==zsgn) {
  601. z = scm_copy_smaller(x, nx, zsgn);
  602. x = SCM_BDIGITS(bigy);
  603. xsgn = SCM_BIGSIGN(bigy);
  604. }
  605. else z = scm_copy_big_dec(bigy, zsgn);
  606. zds = SCM_BDIGITS(z);
  607. if (zsgn) {
  608. if (xsgn) do {
  609. num += x[i];
  610. if (num < 0) {zds[i] &= num + SCM_BIGRAD; num = -1;}
  611. else {zds[i] &= SCM_BIGLO(num); num = 0;}
  612. } while (++i < nx);
  613. else do zds[i] = zds[i] & ~x[i]; while (++i < nx);
  614. /* ========= need to increment zds now =========== */
  615. i = 0; num = 1;
  616. while (i < nx) {
  617. num += zds[i];
  618. zds[i++] = SCM_BIGLO(num);
  619. num = SCM_BIGDN(num);
  620. if (!num) return scm_i_normbig(z);
  621. }
  622. }
  623. else if (xsgn) {
  624. unsigned long int carry = 1;
  625. do {
  626. unsigned long int mask = (SCM_BIGDIG) ~x[i] + carry;
  627. zds[i] = zds[i] & (SCM_BIGDIG) mask;
  628. carry = (mask >= SCM_BIGRAD) ? 1 : 0;
  629. } while (++i < nx);
  630. } else do zds[i] = zds[i] & x[i]; while (++i < nx);
  631. return scm_i_normbig(z);
  632. }
  633. SCM scm_big_test(SCM_BIGDIG *x, size_t nx, int xsgn, SCM bigy)
  634. /* Assumes nx <= SCM_NUMDIGS(bigy) */
  635. /* Assumes xsgn equals either 0 or SCM_BIGSIGNFLAG */
  636. {
  637. SCM_BIGDIG *y;
  638. size_t i = 0;
  639. long num = -1;
  640. if (SCM_BIGSIGN(bigy) & xsgn) return SCM_BOOL_T;
  641. if (SCM_NUMDIGS(bigy) != nx && xsgn) return SCM_BOOL_T;
  642. y = SCM_BDIGITS(bigy);
  643. if (xsgn)
  644. do {
  645. num += x[i];
  646. if (num < 0) {
  647. if (y[i] & ~(num + SCM_BIGRAD)) return SCM_BOOL_T;
  648. num = -1;
  649. }
  650. else {
  651. if (y[i] & ~SCM_BIGLO(num)) return SCM_BOOL_T;
  652. num = 0;
  653. }
  654. } while (++i < nx);
  655. else if SCM_BIGSIGN(bigy)
  656. do {
  657. num += y[i];
  658. if (num < 0) {
  659. if (x[i] & ~(num + SCM_BIGRAD)) return SCM_BOOL_T;
  660. num = -1;
  661. }
  662. else {
  663. if (x[i] & ~SCM_BIGLO(num)) return SCM_BOOL_T;
  664. num = 0;
  665. }
  666. } while (++i < nx);
  667. else
  668. do if (x[i] & y[i]) return SCM_BOOL_T;
  669. while (++i < nx);
  670. return SCM_BOOL_F;
  671. }
  672. #endif
  673. SCM_DEFINE1 (scm_logand, "logand", scm_tc7_asubr,
  674. (SCM n1, SCM n2),
  675. "Return the bitwise AND of the integer arguments.\n\n"
  676. "@lisp\n"
  677. "(logand) @result{} -1\n"
  678. "(logand 7) @result{} 7\n"
  679. "(logand #b111 #b011 #\b001) @result{} 1\n"
  680. "@end lisp")
  681. #define FUNC_NAME s_scm_logand
  682. {
  683. long int nn1;
  684. if (SCM_UNBNDP (n2)) {
  685. if (SCM_UNBNDP (n1)) {
  686. return SCM_MAKINUM (-1);
  687. } else if (!SCM_NUMBERP (n1)) {
  688. SCM_WRONG_TYPE_ARG (SCM_ARG1, n1);
  689. #ifndef SCM_RECKLESS
  690. } else if (SCM_NUMBERP (n1)) {
  691. return n1;
  692. } else {
  693. SCM_WRONG_TYPE_ARG (SCM_ARG1, n1);
  694. #else
  695. } else {
  696. return n1;
  697. #endif
  698. }
  699. }
  700. if (SCM_INUMP (n1)) {
  701. nn1 = SCM_INUM (n1);
  702. if (SCM_INUMP (n2)) {
  703. long nn2 = SCM_INUM (n2);
  704. return SCM_MAKINUM (nn1 & nn2);
  705. } else if SCM_BIGP (n2) {
  706. intbig:
  707. {
  708. # ifndef SCM_DIGSTOOBIG
  709. long z = scm_pseudolong (nn1);
  710. if ((nn1 < 0) && SCM_BIGSIGN (n2)) {
  711. return scm_big_ior ((SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
  712. SCM_BIGSIGNFLAG, n2);
  713. } else {
  714. return scm_big_and ((SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
  715. (nn1 < 0) ? SCM_BIGSIGNFLAG : 0, n2, 0);
  716. }
  717. # else
  718. SCM_BIGDIG zdigs [SCM_DIGSPERLONG];
  719. scm_longdigs (nn1, zdigs);
  720. if ((nn1 < 0) && SCM_BIGSIGN (n2)) {
  721. return scm_big_ior (zdigs, SCM_DIGSPERLONG, SCM_BIGSIGNFLAG, n2);
  722. } else {
  723. return scm_big_and (zdigs, SCM_DIGSPERLONG,
  724. (nn1 < 0) ? SCM_BIGSIGNFLAG : 0, n2, 0);
  725. }
  726. # endif
  727. }
  728. } else {
  729. SCM_WRONG_TYPE_ARG (SCM_ARG2, n2);
  730. }
  731. } else if (SCM_BIGP (n1)) {
  732. if (SCM_INUMP (n2)) {
  733. SCM_SWAP (n1, n2);
  734. nn1 = SCM_INUM (n1);
  735. goto intbig;
  736. } else if (SCM_BIGP (n2)) {
  737. if (SCM_NUMDIGS (n1) > SCM_NUMDIGS (n2)) {
  738. SCM_SWAP (n1, n2);
  739. };
  740. if ((SCM_BIGSIGN (n1)) && SCM_BIGSIGN (n2)) {
  741. return scm_big_ior (SCM_BDIGITS (n1), SCM_NUMDIGS (n1),
  742. SCM_BIGSIGNFLAG, n2);
  743. } else {
  744. return scm_big_and (SCM_BDIGITS (n1), SCM_NUMDIGS (n1),
  745. SCM_BIGSIGN (n1), n2, 0);
  746. }
  747. } else {
  748. SCM_WRONG_TYPE_ARG (SCM_ARG2, n2);
  749. }
  750. } else {
  751. SCM_WRONG_TYPE_ARG (SCM_ARG1, n1);
  752. }
  753. }
  754. #undef FUNC_NAME
  755. SCM_DEFINE1 (scm_logior, "logior", scm_tc7_asubr,
  756. (SCM n1, SCM n2),
  757. "Return the bitwise OR of the integer arguments.\n\n"
  758. "@lisp\n"
  759. "(logior) @result{} 0\n"
  760. "(logior 7) @result{} 7\n"
  761. "(logior #b000 #b001 #b011) @result{} 3\n"
  762. "@end lisp")
  763. #define FUNC_NAME s_scm_logior
  764. {
  765. long int nn1;
  766. if (SCM_UNBNDP (n2)) {
  767. if (SCM_UNBNDP (n1)) {
  768. return SCM_INUM0;
  769. #ifndef SCM_RECKLESS
  770. } else if (SCM_NUMBERP (n1)) {
  771. return n1;
  772. } else {
  773. SCM_WRONG_TYPE_ARG (SCM_ARG1, n1);
  774. #else
  775. } else {
  776. return n1;
  777. #endif
  778. }
  779. }
  780. if (SCM_INUMP (n1)) {
  781. nn1 = SCM_INUM (n1);
  782. if (SCM_INUMP (n2)) {
  783. long nn2 = SCM_INUM (n2);
  784. return SCM_MAKINUM (nn1 | nn2);
  785. } else if (SCM_BIGP (n2)) {
  786. intbig:
  787. {
  788. # ifndef SCM_DIGSTOOBIG
  789. long z = scm_pseudolong (nn1);
  790. if ((!(nn1 < 0)) && !SCM_BIGSIGN (n2)) {
  791. return scm_big_ior ((SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
  792. (nn1 < 0) ? SCM_BIGSIGNFLAG : 0, n2);
  793. } else {
  794. return scm_big_and ((SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
  795. (nn1 < 0) ? SCM_BIGSIGNFLAG : 0, n2, SCM_BIGSIGNFLAG);
  796. }
  797. # else
  798. SCM_BIGDIG zdigs [SCM_DIGSPERLONG];
  799. scm_longdigs (nn1, zdigs);
  800. if ((!(nn1 < 0)) && !SCM_BIGSIGN (n2)) {
  801. return scm_big_ior (zdigs, SCM_DIGSPERLONG,
  802. (nn1 < 0) ? SCM_BIGSIGNFLAG : 0, n2);
  803. } else {
  804. return scm_big_and (zdigs, SCM_DIGSPERLONG,
  805. (nn1 < 0) ? SCM_BIGSIGNFLAG : 0, n2, SCM_BIGSIGNFLAG);
  806. }
  807. # endif
  808. }
  809. } else {
  810. SCM_WRONG_TYPE_ARG (SCM_ARG2, n2);
  811. }
  812. } else if (SCM_BIGP (n1)) {
  813. if (SCM_INUMP (n2)) {
  814. SCM_SWAP (n1, n2);
  815. nn1 = SCM_INUM (n1);
  816. goto intbig;
  817. } else if (SCM_BIGP (n2)) {
  818. if (SCM_NUMDIGS (n1) > SCM_NUMDIGS (n2)) {
  819. SCM_SWAP (n1, n2);
  820. };
  821. if ((!SCM_BIGSIGN (n1)) && !SCM_BIGSIGN (n2)) {
  822. return scm_big_ior (SCM_BDIGITS (n1), SCM_NUMDIGS (n1),
  823. SCM_BIGSIGN (n1), n2);
  824. } else {
  825. return scm_big_and (SCM_BDIGITS (n1), SCM_NUMDIGS (n1),
  826. SCM_BIGSIGN (n1), n2, SCM_BIGSIGNFLAG);
  827. }
  828. } else {
  829. SCM_WRONG_TYPE_ARG (SCM_ARG2, n2);
  830. }
  831. } else {
  832. SCM_WRONG_TYPE_ARG (SCM_ARG1, n1);
  833. }
  834. }
  835. #undef FUNC_NAME
  836. SCM_DEFINE1 (scm_logxor, "logxor", scm_tc7_asubr,
  837. (SCM n1, SCM n2),
  838. "Return the bitwise XOR of the integer arguments. A bit is\n"
  839. "set in the result if it is set in an odd number of arguments.\n"
  840. "@lisp\n"
  841. "(logxor) @result{} 0\n"
  842. "(logxor 7) @result{} 7\n"
  843. "(logxor #b000 #b001 #b011) @result{} 2\n"
  844. "(logxor #b000 #b001 #b011 #b011) @result{} 1\n"
  845. "@end lisp")
  846. #define FUNC_NAME s_scm_logxor
  847. {
  848. long int nn1;
  849. if (SCM_UNBNDP (n2)) {
  850. if (SCM_UNBNDP (n1)) {
  851. return SCM_INUM0;
  852. #ifndef SCM_RECKLESS
  853. } else if (SCM_NUMBERP (n1)) {
  854. return n1;
  855. } else {
  856. SCM_WRONG_TYPE_ARG (SCM_ARG1, n1);
  857. #else
  858. } else {
  859. return n1;
  860. #endif
  861. }
  862. }
  863. if (SCM_INUMP (n1)) {
  864. nn1 = SCM_INUM (n1);
  865. if (SCM_INUMP (n2)) {
  866. long nn2 = SCM_INUM (n2);
  867. return SCM_MAKINUM (nn1 ^ nn2);
  868. } else if (SCM_BIGP (n2)) {
  869. intbig:
  870. {
  871. # ifndef SCM_DIGSTOOBIG
  872. long z = scm_pseudolong (nn1);
  873. return scm_big_xor ((SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
  874. (nn1 < 0) ? SCM_BIGSIGNFLAG : 0, n2);
  875. # else
  876. SCM_BIGDIG zdigs [SCM_DIGSPERLONG];
  877. scm_longdigs (nn1, zdigs);
  878. return scm_big_xor (zdigs, SCM_DIGSPERLONG,
  879. (nn1 < 0) ? SCM_BIGSIGNFLAG : 0, n2);
  880. # endif
  881. }
  882. } else {
  883. SCM_WRONG_TYPE_ARG (SCM_ARG2, n2);
  884. }
  885. } else if (SCM_BIGP (n1)) {
  886. if (SCM_INUMP (n2)) {
  887. SCM_SWAP (n1, n2);
  888. nn1 = SCM_INUM (n1);
  889. goto intbig;
  890. } else if (SCM_BIGP (n2)) {
  891. if (SCM_NUMDIGS(n1) > SCM_NUMDIGS(n2)) {
  892. SCM_SWAP (n1, n2);
  893. }
  894. return scm_big_xor (SCM_BDIGITS (n1), SCM_NUMDIGS (n1),
  895. SCM_BIGSIGN (n1), n2);
  896. } else {
  897. SCM_WRONG_TYPE_ARG (SCM_ARG2, n2);
  898. }
  899. } else {
  900. SCM_WRONG_TYPE_ARG (SCM_ARG1, n1);
  901. }
  902. }
  903. #undef FUNC_NAME
  904. SCM_DEFINE (scm_logtest, "logtest", 2, 0, 0,
  905. (SCM j, SCM k),
  906. "@lisp\n"
  907. "(logtest j k) @equiv{} (not (zero? (logand j k)))\n\n"
  908. "(logtest #b0100 #b1011) @result{} #f\n"
  909. "(logtest #b0100 #b0111) @result{} #t\n"
  910. "@end lisp")
  911. #define FUNC_NAME s_scm_logtest
  912. {
  913. long int nj;
  914. if (SCM_INUMP (j)) {
  915. nj = SCM_INUM (j);
  916. if (SCM_INUMP (k)) {
  917. long nk = SCM_INUM (k);
  918. return SCM_BOOL (nj & nk);
  919. } else if (SCM_BIGP (k)) {
  920. intbig:
  921. {
  922. # ifndef SCM_DIGSTOOBIG
  923. long z = scm_pseudolong (nj);
  924. return scm_big_test ((SCM_BIGDIG *)&z, SCM_DIGSPERLONG,
  925. (nj < 0) ? SCM_BIGSIGNFLAG : 0, k);
  926. # else
  927. SCM_BIGDIG zdigs [SCM_DIGSPERLONG];
  928. scm_longdigs (nj, zdigs);
  929. return scm_big_test (zdigs, SCM_DIGSPERLONG,
  930. (nj < 0) ? SCM_BIGSIGNFLAG : 0, k);
  931. # endif
  932. }
  933. } else {
  934. SCM_WRONG_TYPE_ARG (SCM_ARG2, k);
  935. }
  936. } else if (SCM_BIGP (j)) {
  937. if (SCM_INUMP (k)) {
  938. SCM_SWAP (j, k);
  939. nj = SCM_INUM (j);
  940. goto intbig;
  941. } else if (SCM_BIGP (k)) {
  942. if (SCM_NUMDIGS (j) > SCM_NUMDIGS (k)) {
  943. SCM_SWAP (j, k);
  944. }
  945. return scm_big_test (SCM_BDIGITS (j), SCM_NUMDIGS (j),
  946. SCM_BIGSIGN (j), k);
  947. } else {
  948. SCM_WRONG_TYPE_ARG (SCM_ARG2, k);
  949. }
  950. } else {
  951. SCM_WRONG_TYPE_ARG (SCM_ARG1, j);
  952. }
  953. }
  954. #undef FUNC_NAME
  955. SCM_DEFINE (scm_logbit_p, "logbit?", 2, 0, 0,
  956. (SCM index, SCM j),
  957. "@lisp\n"
  958. "(logbit? index j) @equiv{} (logtest (integer-expt 2 index) j)\n\n"
  959. "(logbit? 0 #b1101) @result{} #t\n"
  960. "(logbit? 1 #b1101) @result{} #f\n"
  961. "(logbit? 2 #b1101) @result{} #t\n"
  962. "(logbit? 3 #b1101) @result{} #t\n"
  963. "(logbit? 4 #b1101) @result{} #f\n"
  964. "@end lisp")
  965. #define FUNC_NAME s_scm_logbit_p
  966. {
  967. unsigned long int iindex;
  968. SCM_VALIDATE_INUM_MIN (SCM_ARG1, index, 0);
  969. iindex = (unsigned long int) SCM_INUM (index);
  970. if (SCM_INUMP (j)) {
  971. {
  972. /* bits above what's in an inum follow the sign bit */
  973. iindex = min (iindex, SCM_LONG_BIT - 1);
  974. return SCM_BOOL ((1L << iindex) & SCM_INUM (j));
  975. }
  976. } else if (SCM_BIGP (j)) {
  977. if (SCM_NUMDIGS (j) * SCM_BITSPERDIG < iindex) {
  978. return SCM_BOOL_F;
  979. } else if (SCM_BIGSIGN (j)) {
  980. long num = -1;
  981. size_t i = 0;
  982. SCM_BIGDIG * x = SCM_BDIGITS (j);
  983. size_t nx = iindex / SCM_BITSPERDIG;
  984. while (1) {
  985. num += x[i];
  986. if (nx == i++) {
  987. return SCM_BOOL (((1L << (iindex % SCM_BITSPERDIG)) & num) == 0);
  988. } else if (num < 0) {
  989. num = -1;
  990. } else {
  991. num = 0;
  992. }
  993. }
  994. } else {
  995. return SCM_BOOL (SCM_BDIGITS (j) [iindex / SCM_BITSPERDIG]
  996. & (1L << (iindex % SCM_BITSPERDIG)));
  997. }
  998. } else {
  999. SCM_WRONG_TYPE_ARG (SCM_ARG2, j);
  1000. }
  1001. }
  1002. #undef FUNC_NAME
  1003. SCM_DEFINE (scm_lognot, "lognot", 1, 0, 0,
  1004. (SCM n),
  1005. "Return the integer which is the ones-complement of the integer\n"
  1006. "argument.\n"
  1007. "\n"
  1008. "@lisp\n"
  1009. "(number->string (lognot #b10000000) 2)\n"
  1010. " @result{} \"-10000001\"\n"
  1011. "(number->string (lognot #b0) 2)\n"
  1012. " @result{} \"-1\"\n"
  1013. "@end lisp")
  1014. #define FUNC_NAME s_scm_lognot
  1015. {
  1016. return scm_difference (SCM_MAKINUM (-1L), n);
  1017. }
  1018. #undef FUNC_NAME
  1019. SCM_DEFINE (scm_integer_expt, "integer-expt", 2, 0, 0,
  1020. (SCM n, SCM k),
  1021. "Return @var{n} raised to the non-negative integer exponent\n"
  1022. "@var{k}.\n"
  1023. "\n"
  1024. "@lisp\n"
  1025. "(integer-expt 2 5)\n"
  1026. " @result{} 32\n"
  1027. "(integer-expt -3 3)\n"
  1028. " @result{} -27\n"
  1029. "@end lisp")
  1030. #define FUNC_NAME s_scm_integer_expt
  1031. {
  1032. SCM acc = SCM_MAKINUM (1L);
  1033. int i2;
  1034. #ifdef SCM_BIGDIG
  1035. /* 0^0 == 1 according to R5RS */
  1036. if (SCM_EQ_P (n, SCM_INUM0) || SCM_EQ_P (n, acc))
  1037. return SCM_FALSEP (scm_zero_p(k)) ? n : acc;
  1038. else if (SCM_EQ_P (n, SCM_MAKINUM (-1L)))
  1039. return SCM_FALSEP (scm_even_p (k)) ? n : acc;
  1040. #endif
  1041. if (SCM_REALP (k))
  1042. {
  1043. double r = SCM_REAL_VALUE (k);
  1044. i2 = r;
  1045. if (i2 != r)
  1046. SCM_WRONG_TYPE_ARG (2, k);
  1047. }
  1048. else
  1049. SCM_VALIDATE_ULONG_COPY (2,k,i2);
  1050. if (i2 < 0)
  1051. {
  1052. i2 = -i2;
  1053. n = scm_divide (n, SCM_UNDEFINED);
  1054. }
  1055. while (1)
  1056. {
  1057. if (0 == i2)
  1058. return acc;
  1059. if (1 == i2)
  1060. return scm_product (acc, n);
  1061. if (i2 & 1)
  1062. acc = scm_product (acc, n);
  1063. n = scm_product (n, n);
  1064. i2 >>= 1;
  1065. }
  1066. }
  1067. #undef FUNC_NAME
  1068. SCM_DEFINE (scm_ash, "ash", 2, 0, 0,
  1069. (SCM n, SCM cnt),
  1070. "The function ash performs an arithmetic shift left by @var{cnt}\n"
  1071. "bits (or shift right, if @var{cnt} is negative). 'Arithmetic'\n"
  1072. "means, that the function does not guarantee to keep the bit\n"
  1073. "structure of @var{n}, but rather guarantees that the result\n"
  1074. "will always be rounded towards minus infinity. Therefore, the\n"
  1075. "results of ash and a corresponding bitwise shift will differ if\n"
  1076. "@var{n} is negative.\n"
  1077. "\n"
  1078. "Formally, the function returns an integer equivalent to\n"
  1079. "@code{(inexact->exact (floor (* @var{n} (expt 2 @var{cnt}))))}.\n"
  1080. "\n"
  1081. "@lisp\n"
  1082. "(number->string (ash #b1 3) 2) @result{} \"1000\"\n"
  1083. "(number->string (ash #b1010 -1) 2) @result{} \"101\"\n"
  1084. "@end lisp")
  1085. #define FUNC_NAME s_scm_ash
  1086. {
  1087. long bits_to_shift;
  1088. #ifndef SCM_BIGDIG
  1089. SCM_VALIDATE_INUM (1, n)
  1090. #endif
  1091. SCM_VALIDATE_INUM (2, cnt);
  1092. bits_to_shift = SCM_INUM (cnt);
  1093. #ifdef SCM_BIGDIG
  1094. if (bits_to_shift < 0) {
  1095. /* Shift right by abs(cnt) bits. This is realized as a division by
  1096. div:=2^abs(cnt). However, to guarantee the floor rounding, negative
  1097. values require some special treatment.
  1098. */
  1099. SCM div = scm_integer_expt (SCM_MAKINUM (2), SCM_MAKINUM (-bits_to_shift));
  1100. if (SCM_FALSEP (scm_negative_p (n)))
  1101. return scm_quotient (n, div);
  1102. else
  1103. return scm_sum (SCM_MAKINUM (-1L),
  1104. scm_quotient (scm_sum (SCM_MAKINUM (1L), n), div));
  1105. } else
  1106. /* Shift left is done by multiplication with 2^CNT */
  1107. return scm_product (n, scm_integer_expt (SCM_MAKINUM (2), cnt));
  1108. #else
  1109. if (bits_to_shift < 0)
  1110. /* Signed right shift (SCM_SRS does it right) by abs(cnt) bits. */
  1111. return SCM_MAKINUM (SCM_SRS (SCM_INUM (n), -bits_to_shift));
  1112. else {
  1113. /* Shift left, but make sure not to leave the range of inums */
  1114. SCM res = SCM_MAKINUM (SCM_INUM (n) << cnt);
  1115. if (SCM_INUM (res) >> cnt != SCM_INUM (n))
  1116. scm_num_overflow (FUNC_NAME);
  1117. return res;
  1118. }
  1119. #endif
  1120. }
  1121. #undef FUNC_NAME
  1122. SCM_DEFINE (scm_bit_extract, "bit-extract", 3, 0, 0,
  1123. (SCM n, SCM start, SCM end),
  1124. "Return the integer composed of the @var{start} (inclusive)\n"
  1125. "through @var{end} (exclusive) bits of @var{n}. The\n"
  1126. "@var{start}th bit becomes the 0-th bit in the result.\n"
  1127. "\n"
  1128. "@lisp\n"
  1129. "(number->string (bit-extract #b1101101010 0 4) 2)\n"
  1130. " @result{} \"1010\"\n"
  1131. "(number->string (bit-extract #b1101101010 4 9) 2)\n"
  1132. " @result{} \"10110\"\n"
  1133. "@end lisp")
  1134. #define FUNC_NAME s_scm_bit_extract
  1135. {
  1136. unsigned long int istart, iend;
  1137. SCM_VALIDATE_INUM_MIN_COPY (2,start,0,istart);
  1138. SCM_VALIDATE_INUM_MIN_COPY (3, end, 0, iend);
  1139. SCM_ASSERT_RANGE (3, end, (iend >= istart));
  1140. if (SCM_INUMP (n)) {
  1141. long int in = SCM_INUM (n);
  1142. unsigned long int bits = iend - istart;
  1143. if (in < 0 && bits >= SCM_I_FIXNUM_BIT)
  1144. {
  1145. /* Since we emulate two's complement encoded numbers, this special
  1146. * case requires us to produce a result that has more bits than can be
  1147. * stored in a fixnum. Thus, we fall back to the more general
  1148. * algorithm that is used for bignums.
  1149. */
  1150. goto generalcase;
  1151. }
  1152. if (istart < SCM_I_FIXNUM_BIT)
  1153. {
  1154. in = in >> istart;
  1155. if (bits < SCM_I_FIXNUM_BIT)
  1156. return SCM_MAKINUM (in & ((1L << bits) - 1));
  1157. else /* we know: in >= 0 */
  1158. return SCM_MAKINUM (in);
  1159. }
  1160. else if (in < 0)
  1161. {
  1162. return SCM_MAKINUM (-1L & ((1L << bits) - 1));
  1163. }
  1164. else
  1165. {
  1166. return SCM_MAKINUM (0);
  1167. }
  1168. } else if (SCM_BIGP (n)) {
  1169. generalcase:
  1170. {
  1171. SCM num1 = SCM_MAKINUM (1L);
  1172. SCM num2 = SCM_MAKINUM (2L);
  1173. SCM bits = SCM_MAKINUM (iend - istart);
  1174. SCM mask = scm_difference (scm_integer_expt (num2, bits), num1);
  1175. return scm_logand (mask, scm_ash (n, SCM_MAKINUM (-istart)));
  1176. }
  1177. } else {
  1178. SCM_WRONG_TYPE_ARG (SCM_ARG1, n);
  1179. }
  1180. }
  1181. #undef FUNC_NAME
  1182. static const char scm_logtab[] = {
  1183. 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
  1184. };
  1185. SCM_DEFINE (scm_logcount, "logcount", 1, 0, 0,
  1186. (SCM n),
  1187. "Return the number of bits in integer @var{n}. If integer is\n"
  1188. "positive, the 1-bits in its binary representation are counted.\n"
  1189. "If negative, the 0-bits in its two's-complement binary\n"
  1190. "representation are counted. If 0, 0 is returned.\n"
  1191. "\n"
  1192. "@lisp\n"
  1193. "(logcount #b10101010)\n"
  1194. " @result{} 4\n"
  1195. "(logcount 0)\n"
  1196. " @result{} 0\n"
  1197. "(logcount -2)\n"
  1198. " @result{} 1\n"
  1199. "@end lisp")
  1200. #define FUNC_NAME s_scm_logcount
  1201. {
  1202. if (SCM_INUMP (n)) {
  1203. unsigned long int c = 0;
  1204. long int nn = SCM_INUM (n);
  1205. if (nn < 0) {
  1206. nn = -1 - nn;
  1207. };
  1208. while (nn) {
  1209. c += scm_logtab[15 & nn];
  1210. nn >>= 4;
  1211. };
  1212. return SCM_MAKINUM (c);
  1213. } else if (SCM_BIGP (n)) {
  1214. if (SCM_BIGSIGN (n)) {
  1215. return scm_logcount (scm_difference (SCM_MAKINUM (-1L), n));
  1216. } else {
  1217. unsigned long int c = 0;
  1218. size_t i = SCM_NUMDIGS (n);
  1219. SCM_BIGDIG * ds = SCM_BDIGITS (n);
  1220. while (i--) {
  1221. SCM_BIGDIG d;
  1222. for (d = ds[i]; d; d >>= 4) {
  1223. c += scm_logtab[15 & d];
  1224. }
  1225. }
  1226. return SCM_MAKINUM (c);
  1227. }
  1228. } else {
  1229. SCM_WRONG_TYPE_ARG (SCM_ARG1, n);
  1230. }
  1231. }
  1232. #undef FUNC_NAME
  1233. static const char scm_ilentab[] = {
  1234. 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
  1235. };
  1236. SCM_DEFINE (scm_integer_length, "integer-length", 1, 0, 0,
  1237. (SCM n),
  1238. "Return the number of bits necessary to represent @var{n}.\n"
  1239. "\n"
  1240. "@lisp\n"
  1241. "(integer-length #b10101010)\n"
  1242. " @result{} 8\n"
  1243. "(integer-length 0)\n"
  1244. " @result{} 0\n"
  1245. "(integer-length #b1111)\n"
  1246. " @result{} 4\n"
  1247. "@end lisp")
  1248. #define FUNC_NAME s_scm_integer_length
  1249. {
  1250. if (SCM_INUMP (n)) {
  1251. unsigned long int c = 0;
  1252. unsigned int l = 4;
  1253. long int nn = SCM_INUM (n);
  1254. if (nn < 0) {
  1255. nn = -1 - nn;
  1256. };
  1257. while (nn) {
  1258. c += 4;
  1259. l = scm_ilentab [15 & nn];
  1260. nn >>= 4;
  1261. };
  1262. return SCM_MAKINUM (c - 4 + l);
  1263. } else if (SCM_BIGP (n)) {
  1264. if (SCM_BIGSIGN (n)) {
  1265. return scm_integer_length (scm_difference (SCM_MAKINUM (-1L), n));
  1266. } else {
  1267. unsigned long int digs = SCM_NUMDIGS (n) - 1;
  1268. unsigned long int c = digs * SCM_BITSPERDIG;
  1269. unsigned int l = 4;
  1270. SCM_BIGDIG * ds = SCM_BDIGITS (n);
  1271. SCM_BIGDIG d = ds [digs];
  1272. while (d) {
  1273. c += 4;
  1274. l = scm_ilentab [15 & d];
  1275. d >>= 4;
  1276. };
  1277. return SCM_MAKINUM (c - 4 + l);
  1278. }
  1279. } else {
  1280. SCM_WRONG_TYPE_ARG (SCM_ARG1, n);
  1281. }
  1282. }
  1283. #undef FUNC_NAME
  1284. #ifdef SCM_BIGDIG
  1285. static const char s_bignum[] = "bignum";
  1286. SCM
  1287. scm_i_mkbig (size_t nlen, int sign)
  1288. {
  1289. SCM v;
  1290. SCM_BIGDIG *base;
  1291. if (((nlen << SCM_BIGSIZEFIELD) >> SCM_BIGSIZEFIELD) != nlen)
  1292. scm_memory_error (s_bignum);
  1293. base = scm_must_malloc (nlen * sizeof (SCM_BIGDIG), s_bignum);
  1294. SCM_NEWCELL (v);
  1295. SCM_SET_BIGNUM_BASE (v, base);
  1296. SCM_SETNUMDIGS (v, nlen, sign);
  1297. return v;
  1298. }
  1299. SCM
  1300. scm_i_big2inum (SCM b, size_t l)
  1301. {
  1302. unsigned long num = 0;
  1303. SCM_BIGDIG *tmp = SCM_BDIGITS (b);
  1304. while (l--)
  1305. num = SCM_BIGUP (num) + tmp[l];
  1306. if (!SCM_BIGSIGN (b))
  1307. {
  1308. if (SCM_POSFIXABLE (num))
  1309. return SCM_MAKINUM (num);
  1310. }
  1311. else if (num <= -SCM_MOST_NEGATIVE_FIXNUM)
  1312. return SCM_MAKINUM (-num);
  1313. return b;
  1314. }
  1315. static const char s_adjbig[] = "scm_i_adjbig";
  1316. SCM
  1317. scm_i_adjbig (SCM b, size_t nlen)
  1318. {
  1319. size_t nsiz = nlen;
  1320. if (((nsiz << SCM_BIGSIZEFIELD) >> SCM_BIGSIZEFIELD) != nlen)
  1321. scm_memory_error (s_adjbig);
  1322. SCM_DEFER_INTS;
  1323. {
  1324. SCM_BIGDIG *digits
  1325. = ((SCM_BIGDIG *)
  1326. scm_must_realloc ((char *) SCM_BDIGITS (b),
  1327. (long) (SCM_NUMDIGS (b) * sizeof (SCM_BIGDIG)),
  1328. (long) (nsiz * sizeof (SCM_BIGDIG)), s_bignum));
  1329. SCM_SET_BIGNUM_BASE (b, digits);
  1330. SCM_SETNUMDIGS (b, nsiz, SCM_BIGSIGN (b));
  1331. }
  1332. SCM_ALLOW_INTS;
  1333. return b;
  1334. }
  1335. SCM
  1336. scm_i_normbig (SCM b)
  1337. {
  1338. #ifndef _UNICOS
  1339. size_t nlen = SCM_NUMDIGS (b);
  1340. #else
  1341. int nlen = SCM_NUMDIGS (b); /* unsigned nlen breaks on Cray when nlen => 0 */
  1342. #endif
  1343. SCM_BIGDIG *zds = SCM_BDIGITS (b);
  1344. while (nlen-- && !zds[nlen]);
  1345. nlen++;
  1346. if (nlen * SCM_BITSPERDIG / SCM_CHAR_BIT <= sizeof (SCM))
  1347. if (SCM_INUMP (b = scm_i_big2inum (b, (size_t) nlen)))
  1348. return b;
  1349. if (SCM_NUMDIGS (b) == nlen)
  1350. return b;
  1351. return scm_i_adjbig (b, (size_t) nlen);
  1352. }
  1353. SCM
  1354. scm_i_copybig (SCM b, int sign)
  1355. {
  1356. size_t i = SCM_NUMDIGS (b);
  1357. SCM ans = scm_i_mkbig (i, sign);
  1358. SCM_BIGDIG *src = SCM_BDIGITS (b), *dst = SCM_BDIGITS (ans);
  1359. while (i--)
  1360. dst[i] = src[i];
  1361. return ans;
  1362. }
  1363. int
  1364. scm_bigcomp (SCM x, SCM y)
  1365. {
  1366. int xsign = SCM_BIGSIGN (x);
  1367. int ysign = SCM_BIGSIGN (y);
  1368. size_t xlen, ylen;
  1369. /* Look at the signs, first. */
  1370. if (ysign < xsign)
  1371. return 1;
  1372. if (ysign > xsign)
  1373. return -1;
  1374. /* They're the same sign, so see which one has more digits. Note
  1375. that, if they are negative, the longer number is the lesser. */
  1376. ylen = SCM_NUMDIGS (y);
  1377. xlen = SCM_NUMDIGS (x);
  1378. if (ylen > xlen)
  1379. return (xsign) ? -1 : 1;
  1380. if (ylen < xlen)
  1381. return (xsign) ? 1 : -1;
  1382. /* They have the same number of digits, so find the most significant
  1383. digit where they differ. */
  1384. while (xlen)
  1385. {
  1386. --xlen;
  1387. if (SCM_BDIGITS (y)[xlen] != SCM_BDIGITS (x)[xlen])
  1388. /* Make the discrimination based on the digit that differs. */
  1389. return ((SCM_BDIGITS (y)[xlen] > SCM_BDIGITS (x)[xlen])
  1390. ? (xsign ? -1 : 1)
  1391. : (xsign ? 1 : -1));
  1392. }
  1393. /* The numbers are identical. */
  1394. return 0;
  1395. }
  1396. #ifndef SCM_DIGSTOOBIG
  1397. long
  1398. scm_pseudolong (long x)
  1399. {
  1400. union
  1401. {
  1402. long l;
  1403. SCM_BIGDIG bd[SCM_DIGSPERLONG];
  1404. }
  1405. p;
  1406. size_t i = 0;
  1407. if (x < 0)
  1408. x = -x;
  1409. while (i < SCM_DIGSPERLONG)
  1410. {
  1411. p.bd[i++] = SCM_BIGLO (x);
  1412. x = SCM_BIGDN (x);
  1413. }
  1414. /* p.bd[0] = SCM_BIGLO(x); p.bd[1] = SCM_BIGDN(x); */
  1415. return p.l;
  1416. }
  1417. #else
  1418. void
  1419. scm_longdigs (long x, SCM_BIGDIG digs[])
  1420. {
  1421. size_t i = 0;
  1422. if (x < 0)
  1423. x = -x;
  1424. while (i < SCM_DIGSPERLONG)
  1425. {
  1426. digs[i++] = SCM_BIGLO (x);
  1427. x = SCM_BIGDN (x);
  1428. }
  1429. }
  1430. #endif
  1431. SCM
  1432. scm_addbig (SCM_BIGDIG *x, size_t nx, int xsgn, SCM bigy, int sgny)
  1433. {
  1434. /* Assumes nx <= SCM_NUMDIGS(bigy) */
  1435. /* Assumes xsgn and sgny scm_equal either 0 or SCM_BIGSIGNFLAG */
  1436. long num = 0;
  1437. size_t i = 0, ny = SCM_NUMDIGS (bigy);
  1438. SCM z = scm_i_copybig (bigy, SCM_BIGSIGN (bigy) ^ sgny);
  1439. SCM_BIGDIG *zds = SCM_BDIGITS (z);
  1440. if (xsgn ^ SCM_BIGSIGN (z))
  1441. {
  1442. do
  1443. {
  1444. num += (long) zds[i] - x[i];
  1445. if (num < 0)
  1446. {
  1447. zds[i] = num + SCM_BIGRAD;
  1448. num = -1;
  1449. }
  1450. else
  1451. {
  1452. zds[i] = SCM_BIGLO (num);
  1453. num = 0;
  1454. }
  1455. }
  1456. while (++i < nx);
  1457. if (num && nx == ny)
  1458. {
  1459. num = 1;
  1460. i = 0;
  1461. SCM_SET_CELL_WORD_0 (z, SCM_CELL_WORD_0 (z) ^ SCM_BIGSIGNFLAG);
  1462. do
  1463. {
  1464. num += (SCM_BIGRAD - 1) - zds[i];
  1465. zds[i++] = SCM_BIGLO (num);
  1466. num = SCM_BIGDN (num);
  1467. }
  1468. while (i < ny);
  1469. }
  1470. else
  1471. while (i < ny)
  1472. {
  1473. num += zds[i];
  1474. if (num < 0)
  1475. {
  1476. zds[i++] = num + SCM_BIGRAD;
  1477. num = -1;
  1478. }
  1479. else
  1480. {
  1481. zds[i++] = SCM_BIGLO (num);
  1482. num = 0;
  1483. }
  1484. }
  1485. }
  1486. else
  1487. {
  1488. do
  1489. {
  1490. num += (long) zds[i] + x[i];
  1491. zds[i++] = SCM_BIGLO (num);
  1492. num = SCM_BIGDN (num);
  1493. }
  1494. while (i < nx);
  1495. if (!num)
  1496. return z;
  1497. while (i < ny)
  1498. {
  1499. num += zds[i];
  1500. zds[i++] = SCM_BIGLO (num);
  1501. num = SCM_BIGDN (num);
  1502. if (!num)
  1503. return z;
  1504. }
  1505. if (num)
  1506. {
  1507. z = scm_i_adjbig (z, ny + 1);
  1508. SCM_BDIGITS (z)[ny] = num;
  1509. return z;
  1510. }
  1511. }
  1512. return scm_i_normbig (z);
  1513. }
  1514. SCM
  1515. scm_mulbig (SCM_BIGDIG *x, size_t nx, SCM_BIGDIG *y, size_t ny, int sgn)
  1516. {
  1517. size_t i = 0, j = nx + ny;
  1518. unsigned long n = 0;
  1519. SCM z = scm_i_mkbig (j, sgn);
  1520. SCM_BIGDIG *zds = SCM_BDIGITS (z);
  1521. while (j--)
  1522. zds[j] = 0;
  1523. do
  1524. {
  1525. j = 0;
  1526. if (x[i])
  1527. {
  1528. do
  1529. {
  1530. n += zds[i + j] + ((unsigned long) x[i] * y[j]);
  1531. zds[i + j++] = SCM_BIGLO (n);
  1532. n = SCM_BIGDN (n);
  1533. }
  1534. while (j < ny);
  1535. if (n)
  1536. {
  1537. zds[i + j] = n;
  1538. n = 0;
  1539. }
  1540. }
  1541. }
  1542. while (++i < nx);
  1543. return scm_i_normbig (z);
  1544. }
  1545. unsigned int
  1546. scm_divbigdig (SCM_BIGDIG * ds, size_t h, SCM_BIGDIG div)
  1547. {
  1548. register unsigned long t2 = 0;
  1549. while (h--)
  1550. {
  1551. t2 = SCM_BIGUP (t2) + ds[h];
  1552. ds[h] = t2 / div;
  1553. t2 %= div;
  1554. }
  1555. return t2;
  1556. }
  1557. static SCM
  1558. scm_divbigint (SCM x, long z, int sgn, int mode)
  1559. {
  1560. if (z < 0)
  1561. z = -z;
  1562. if (z < SCM_BIGRAD)
  1563. {
  1564. register unsigned long t2 = 0;
  1565. register SCM_BIGDIG *ds = SCM_BDIGITS (x);
  1566. size_t nd = SCM_NUMDIGS (x);
  1567. while (nd--)
  1568. t2 = (SCM_BIGUP (t2) + ds[nd]) % z;
  1569. if (mode && t2)
  1570. t2 = z - t2;
  1571. return SCM_MAKINUM (sgn ? -t2 : t2);
  1572. }
  1573. {
  1574. #ifndef SCM_DIGSTOOBIG
  1575. unsigned long t2 = scm_pseudolong (z);
  1576. return scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
  1577. (SCM_BIGDIG *) & t2, SCM_DIGSPERLONG,
  1578. sgn, mode);
  1579. #else
  1580. SCM_BIGDIG t2[SCM_DIGSPERLONG];
  1581. scm_longdigs (z, t2);
  1582. return scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
  1583. t2, SCM_DIGSPERLONG,
  1584. sgn, mode);
  1585. #endif
  1586. }
  1587. }
  1588. static SCM
  1589. scm_divbigbig (SCM_BIGDIG *x, size_t nx, SCM_BIGDIG *y, size_t ny, int sgn, int modes)
  1590. {
  1591. /* modes description
  1592. 0 remainder
  1593. 1 scm_modulo
  1594. 2 quotient
  1595. 3 quotient but returns SCM_UNDEFINED if division is not exact. */
  1596. size_t i = 0, j = 0;
  1597. long num = 0;
  1598. unsigned long t2 = 0;
  1599. SCM z, newy;
  1600. SCM_BIGDIG d = 0, qhat, *zds, *yds;
  1601. /* algorithm requires nx >= ny */
  1602. if (nx < ny)
  1603. switch (modes)
  1604. {
  1605. case 0: /* remainder -- just return x */
  1606. z = scm_i_mkbig (nx, sgn);
  1607. zds = SCM_BDIGITS (z);
  1608. do
  1609. {
  1610. zds[i] = x[i];
  1611. }
  1612. while (++i < nx);
  1613. return z;
  1614. case 1: /* scm_modulo -- return y-x */
  1615. z = scm_i_mkbig (ny, sgn);
  1616. zds = SCM_BDIGITS (z);
  1617. do
  1618. {
  1619. num += (long) y[i] - x[i];
  1620. if (num < 0)
  1621. {
  1622. zds[i] = num + SCM_BIGRAD;
  1623. num = -1;
  1624. }
  1625. else
  1626. {
  1627. zds[i] = num;
  1628. num = 0;
  1629. }
  1630. }
  1631. while (++i < nx);
  1632. while (i < ny)
  1633. {
  1634. num += y[i];
  1635. if (num < 0)
  1636. {
  1637. zds[i++] = num + SCM_BIGRAD;
  1638. num = -1;
  1639. }
  1640. else
  1641. {
  1642. zds[i++] = num;
  1643. num = 0;
  1644. }
  1645. }
  1646. goto doadj;
  1647. case 2:
  1648. return SCM_INUM0; /* quotient is zero */
  1649. case 3:
  1650. return SCM_UNDEFINED; /* the division is not exact */
  1651. }
  1652. z = scm_i_mkbig (nx == ny ? nx + 2 : nx + 1, sgn);
  1653. zds = SCM_BDIGITS (z);
  1654. if (nx == ny)
  1655. zds[nx + 1] = 0;
  1656. while (!y[ny - 1])
  1657. ny--; /* in case y came in as a psuedolong */
  1658. if (y[ny - 1] < (SCM_BIGRAD >> 1))
  1659. { /* normalize operands */
  1660. d = SCM_BIGRAD / (y[ny - 1] + 1);
  1661. newy = scm_i_mkbig (ny, 0);
  1662. yds = SCM_BDIGITS (newy);
  1663. while (j < ny)
  1664. {
  1665. t2 += (unsigned long) y[j] * d;
  1666. yds[j++] = SCM_BIGLO (t2);
  1667. t2 = SCM_BIGDN (t2);
  1668. }
  1669. y = yds;
  1670. j = 0;
  1671. t2 = 0;
  1672. while (j < nx)
  1673. {
  1674. t2 += (unsigned long) x[j] * d;
  1675. zds[j++] = SCM_BIGLO (t2);
  1676. t2 = SCM_BIGDN (t2);
  1677. }
  1678. zds[j] = t2;
  1679. }
  1680. else
  1681. {
  1682. zds[j = nx] = 0;
  1683. while (j--)
  1684. zds[j] = x[j];
  1685. }
  1686. j = nx == ny ? nx + 1 : nx; /* dividend needs more digits than divisor */
  1687. do
  1688. { /* loop over digits of quotient */
  1689. if (zds[j] == y[ny - 1])
  1690. qhat = SCM_BIGRAD - 1;
  1691. else
  1692. qhat = (SCM_BIGUP (zds[j]) + zds[j - 1]) / y[ny - 1];
  1693. if (!qhat)
  1694. continue;
  1695. i = 0;
  1696. num = 0;
  1697. t2 = 0;
  1698. do
  1699. { /* multiply and subtract */
  1700. t2 += (unsigned long) y[i] * qhat;
  1701. num += zds[j - ny + i] - SCM_BIGLO (t2);
  1702. if (num < 0)
  1703. {
  1704. zds[j - ny + i] = num + SCM_BIGRAD;
  1705. num = -1;
  1706. }
  1707. else
  1708. {
  1709. zds[j - ny + i] = num;
  1710. num = 0;
  1711. }
  1712. t2 = SCM_BIGDN (t2);
  1713. }
  1714. while (++i < ny);
  1715. num += zds[j - ny + i] - t2; /* borrow from high digit; don't update */
  1716. while (num)
  1717. { /* "add back" required */
  1718. i = 0;
  1719. num = 0;
  1720. qhat--;
  1721. do
  1722. {
  1723. num += (long) zds[j - ny + i] + y[i];
  1724. zds[j - ny + i] = SCM_BIGLO (num);
  1725. num = SCM_BIGDN (num);
  1726. }
  1727. while (++i < ny);
  1728. num--;
  1729. }
  1730. if (modes & 2)
  1731. zds[j] = qhat;
  1732. }
  1733. while (--j >= ny);
  1734. switch (modes)
  1735. {
  1736. case 3: /* check that remainder==0 */
  1737. for (j = ny; j && !zds[j - 1]; --j);
  1738. if (j)
  1739. return SCM_UNDEFINED;
  1740. case 2: /* move quotient down in z */
  1741. j = (nx == ny ? nx + 2 : nx + 1) - ny;
  1742. for (i = 0; i < j; i++)
  1743. zds[i] = zds[i + ny];
  1744. ny = i;
  1745. break;
  1746. case 1: /* subtract for scm_modulo */
  1747. i = 0;
  1748. num = 0;
  1749. j = 0;
  1750. do
  1751. {
  1752. num += y[i] - zds[i];
  1753. j = j | zds[i];
  1754. if (num < 0)
  1755. {
  1756. zds[i] = num + SCM_BIGRAD;
  1757. num = -1;
  1758. }
  1759. else
  1760. {
  1761. zds[i] = num;
  1762. num = 0;
  1763. }
  1764. }
  1765. while (++i < ny);
  1766. if (!j)
  1767. return SCM_INUM0;
  1768. case 0: /* just normalize remainder */
  1769. if (d)
  1770. scm_divbigdig (zds, ny, d);
  1771. }
  1772. doadj:
  1773. for (j = ny; j && !zds[j - 1]; --j);
  1774. if (j * SCM_BITSPERDIG <= sizeof (SCM) * SCM_CHAR_BIT)
  1775. if (SCM_INUMP (z = scm_i_big2inum (z, j)))
  1776. return z;
  1777. return scm_i_adjbig (z, j);
  1778. }
  1779. #endif
  1780. /*** NUMBERS -> STRINGS ***/
  1781. int scm_dblprec;
  1782. static const double fx[] =
  1783. { 0.0, 5e-1, 5e-2, 5e-3, 5e-4, 5e-5,
  1784. 5e-6, 5e-7, 5e-8, 5e-9, 5e-10,
  1785. 5e-11, 5e-12, 5e-13, 5e-14, 5e-15,
  1786. 5e-16, 5e-17, 5e-18, 5e-19, 5e-20};
  1787. static size_t
  1788. idbl2str (double f, char *a)
  1789. {
  1790. int efmt, dpt, d, i, wp = scm_dblprec;
  1791. size_t ch = 0;
  1792. int exp = 0;
  1793. if (f == 0.0)
  1794. goto zero; /*{a[0]='0'; a[1]='.'; a[2]='0'; return 3;} */
  1795. if (f < 0.0)
  1796. {
  1797. f = -f;
  1798. a[ch++] = '-';
  1799. }
  1800. else if (f > 0.0);
  1801. else
  1802. goto funny;
  1803. if (IS_INF (f))
  1804. {
  1805. if (ch == 0)
  1806. a[ch++] = '+';
  1807. funny:
  1808. a[ch++] = '#';
  1809. a[ch++] = '.';
  1810. a[ch++] = '#';
  1811. return ch;
  1812. }
  1813. #ifdef DBL_MIN_10_EXP /* Prevent unnormalized values, as from
  1814. make-uniform-vector, from causing infinite loops. */
  1815. while (f < 1.0)
  1816. {
  1817. f *= 10.0;
  1818. if (exp-- < DBL_MIN_10_EXP)
  1819. goto funny;
  1820. }
  1821. while (f > 10.0)
  1822. {
  1823. f *= 0.10;
  1824. if (exp++ > DBL_MAX_10_EXP)
  1825. goto funny;
  1826. }
  1827. #else
  1828. while (f < 1.0)
  1829. {
  1830. f *= 10.0;
  1831. exp--;
  1832. }
  1833. while (f > 10.0)
  1834. {
  1835. f /= 10.0;
  1836. exp++;
  1837. }
  1838. #endif
  1839. if (f + fx[wp] >= 10.0)
  1840. {
  1841. f = 1.0;
  1842. exp++;
  1843. }
  1844. zero:
  1845. #ifdef ENGNOT
  1846. dpt = (exp + 9999) % 3;
  1847. exp -= dpt++;
  1848. efmt = 1;
  1849. #else
  1850. efmt = (exp < -3) || (exp > wp + 2);
  1851. if (!efmt)
  1852. {
  1853. if (exp < 0)
  1854. {
  1855. a[ch++] = '0';
  1856. a[ch++] = '.';
  1857. dpt = exp;
  1858. while (++dpt)
  1859. a[ch++] = '0';
  1860. }
  1861. else
  1862. dpt = exp + 1;
  1863. }
  1864. else
  1865. dpt = 1;
  1866. #endif
  1867. do
  1868. {
  1869. d = f;
  1870. f -= d;
  1871. a[ch++] = d + '0';
  1872. if (f < fx[wp])
  1873. break;
  1874. if (f + fx[wp] >= 1.0)
  1875. {
  1876. a[ch - 1]++;
  1877. break;
  1878. }
  1879. f *= 10.0;
  1880. if (!(--dpt))
  1881. a[ch++] = '.';
  1882. }
  1883. while (wp--);
  1884. if (dpt > 0)
  1885. {
  1886. #ifndef ENGNOT
  1887. if ((dpt > 4) && (exp > 6))
  1888. {
  1889. d = (a[0] == '-' ? 2 : 1);
  1890. for (i = ch++; i > d; i--)
  1891. a[i] = a[i - 1];
  1892. a[d] = '.';
  1893. efmt = 1;
  1894. }
  1895. else
  1896. #endif
  1897. {
  1898. while (--dpt)
  1899. a[ch++] = '0';
  1900. a[ch++] = '.';
  1901. }
  1902. }
  1903. if (a[ch - 1] == '.')
  1904. a[ch++] = '0'; /* trailing zero */
  1905. if (efmt && exp)
  1906. {
  1907. a[ch++] = 'e';
  1908. if (exp < 0)
  1909. {
  1910. exp = -exp;
  1911. a[ch++] = '-';
  1912. }
  1913. for (i = 10; i <= exp; i *= 10);
  1914. for (i /= 10; i; i /= 10)
  1915. {
  1916. a[ch++] = exp / i + '0';
  1917. exp %= i;
  1918. }
  1919. }
  1920. return ch;
  1921. }
  1922. static size_t
  1923. iflo2str (SCM flt, char *str)
  1924. {
  1925. size_t i;
  1926. if (SCM_SLOPPY_REALP (flt))
  1927. i = idbl2str (SCM_REAL_VALUE (flt), str);
  1928. else
  1929. {
  1930. i = idbl2str (SCM_COMPLEX_REAL (flt), str);
  1931. if (SCM_COMPLEX_IMAG (flt) != 0.0)
  1932. {
  1933. if (0 <= SCM_COMPLEX_IMAG (flt))
  1934. str[i++] = '+';
  1935. i += idbl2str (SCM_COMPLEX_IMAG (flt), &str[i]);
  1936. str[i++] = 'i';
  1937. }
  1938. }
  1939. return i;
  1940. }
  1941. /* convert a long to a string (unterminated). returns the number of
  1942. characters in the result.
  1943. rad is output base
  1944. p is destination: worst case (base 2) is SCM_INTBUFLEN */
  1945. size_t
  1946. scm_iint2str (long num, int rad, char *p)
  1947. {
  1948. size_t j = 1;
  1949. size_t i;
  1950. unsigned long n = (num < 0) ? -num : num;
  1951. for (n /= rad; n > 0; n /= rad)
  1952. j++;
  1953. i = j;
  1954. if (num < 0)
  1955. {
  1956. *p++ = '-';
  1957. j++;
  1958. n = -num;
  1959. }
  1960. else
  1961. n = num;
  1962. while (i--)
  1963. {
  1964. int d = n % rad;
  1965. n /= rad;
  1966. p[i] = d + ((d < 10) ? '0' : 'a' - 10);
  1967. }
  1968. return j;
  1969. }
  1970. #ifdef SCM_BIGDIG
  1971. static SCM
  1972. big2str (SCM b, unsigned int radix)
  1973. {
  1974. SCM t = scm_i_copybig (b, 0); /* sign of temp doesn't matter */
  1975. register SCM_BIGDIG *ds = SCM_BDIGITS (t);
  1976. size_t i = SCM_NUMDIGS (t);
  1977. size_t j = radix == 16 ? (SCM_BITSPERDIG * i) / 4 + 2
  1978. : radix >= 10 ? (SCM_BITSPERDIG * i * 241L) / 800 + 2
  1979. : (SCM_BITSPERDIG * i) + 2;
  1980. size_t k = 0;
  1981. size_t radct = 0;
  1982. SCM_BIGDIG radpow = 1, radmod = 0;
  1983. SCM ss = scm_allocate_string (j);
  1984. char *s = SCM_STRING_CHARS (ss), c;
  1985. while ((long) radpow * radix < SCM_BIGRAD)
  1986. {
  1987. radpow *= radix;
  1988. radct++;
  1989. }
  1990. while ((i || radmod) && j)
  1991. {
  1992. if (k == 0)
  1993. {
  1994. radmod = (SCM_BIGDIG) scm_divbigdig (ds, i, radpow);
  1995. k = radct;
  1996. if (!ds[i - 1])
  1997. i--;
  1998. }
  1999. c = radmod % radix;
  2000. radmod /= radix;
  2001. k--;
  2002. s[--j] = c < 10 ? c + '0' : c + 'a' - 10;
  2003. }
  2004. if (SCM_BIGSIGN (b))
  2005. s[--j] = '-';
  2006. if (j > 0)
  2007. {
  2008. /* The pre-reserved string length was too large. */
  2009. unsigned long int length = SCM_STRING_LENGTH (ss);
  2010. ss = scm_substring (ss, SCM_MAKINUM (j), SCM_MAKINUM (length));
  2011. }
  2012. return scm_return_first (ss, t);
  2013. }
  2014. #endif
  2015. SCM_DEFINE (scm_number_to_string, "number->string", 1, 1, 0,
  2016. (SCM n, SCM radix),
  2017. "Return a string holding the external representation of the\n"
  2018. "number @var{n} in the given @var{radix}. If @var{n} is\n"
  2019. "inexact, a radix of 10 will be used.")
  2020. #define FUNC_NAME s_scm_number_to_string
  2021. {
  2022. int base;
  2023. if (SCM_UNBNDP (radix)) {
  2024. base = 10;
  2025. } else {
  2026. SCM_VALIDATE_INUM (2, radix);
  2027. base = SCM_INUM (radix);
  2028. SCM_ASSERT_RANGE (2, radix, base >= 2);
  2029. }
  2030. if (SCM_INUMP (n)) {
  2031. char num_buf [SCM_INTBUFLEN];
  2032. size_t length = scm_iint2str (SCM_INUM (n), base, num_buf);
  2033. return scm_mem2string (num_buf, length);
  2034. } else if (SCM_BIGP (n)) {
  2035. return big2str (n, (unsigned int) base);
  2036. } else if (SCM_INEXACTP (n)) {
  2037. char num_buf [FLOBUFLEN];
  2038. return scm_mem2string (num_buf, iflo2str (n, num_buf));
  2039. } else {
  2040. SCM_WRONG_TYPE_ARG (1, n);
  2041. }
  2042. }
  2043. #undef FUNC_NAME
  2044. /* These print routines are stubbed here so that scm_repl.c doesn't need
  2045. SCM_BIGDIG conditionals */
  2046. int
  2047. scm_print_real (SCM sexp, SCM port, scm_print_state *pstate SCM_UNUSED)
  2048. {
  2049. char num_buf[FLOBUFLEN];
  2050. scm_lfwrite (num_buf, iflo2str (sexp, num_buf), port);
  2051. return !0;
  2052. }
  2053. int
  2054. scm_print_complex (SCM sexp, SCM port, scm_print_state *pstate SCM_UNUSED)
  2055. {
  2056. char num_buf[FLOBUFLEN];
  2057. scm_lfwrite (num_buf, iflo2str (sexp, num_buf), port);
  2058. return !0;
  2059. }
  2060. int
  2061. scm_bigprint (SCM exp, SCM port, scm_print_state *pstate SCM_UNUSED)
  2062. {
  2063. #ifdef SCM_BIGDIG
  2064. exp = big2str (exp, (unsigned int) 10);
  2065. scm_lfwrite (SCM_STRING_CHARS (exp), (size_t) SCM_STRING_LENGTH (exp), port);
  2066. #else
  2067. scm_ipruk ("bignum", exp, port);
  2068. #endif
  2069. return !0;
  2070. }
  2071. /*** END nums->strs ***/
  2072. /*** STRINGS -> NUMBERS ***/
  2073. static SCM
  2074. scm_small_istr2int (char *str, long len, long radix)
  2075. {
  2076. register long n = 0, ln;
  2077. register int c;
  2078. register int i = 0;
  2079. int lead_neg = 0;
  2080. if (0 >= len)
  2081. return SCM_BOOL_F; /* zero scm_length */
  2082. switch (*str)
  2083. { /* leading sign */
  2084. case '-':
  2085. lead_neg = 1;
  2086. case '+':
  2087. if (++i == len)
  2088. return SCM_BOOL_F; /* bad if lone `+' or `-' */
  2089. }
  2090. do
  2091. {
  2092. switch (c = str[i++])
  2093. {
  2094. case DIGITS:
  2095. c = c - '0';
  2096. goto accumulate;
  2097. case 'A':
  2098. case 'B':
  2099. case 'C':
  2100. case 'D':
  2101. case 'E':
  2102. case 'F':
  2103. c = c - 'A' + 10;
  2104. goto accumulate;
  2105. case 'a':
  2106. case 'b':
  2107. case 'c':
  2108. case 'd':
  2109. case 'e':
  2110. case 'f':
  2111. c = c - 'a' + 10;
  2112. accumulate:
  2113. if (c >= radix)
  2114. return SCM_BOOL_F; /* bad digit for radix */
  2115. ln = n;
  2116. n = n * radix - c;
  2117. /* Negation is a workaround for HP700 cc bug */
  2118. if (n > ln || (-n > -SCM_MOST_NEGATIVE_FIXNUM))
  2119. goto ovfl;
  2120. break;
  2121. default:
  2122. return SCM_BOOL_F; /* not a digit */
  2123. }
  2124. }
  2125. while (i < len);
  2126. if (!lead_neg)
  2127. if ((n = -n) > SCM_MOST_POSITIVE_FIXNUM)
  2128. goto ovfl;
  2129. return SCM_MAKINUM (n);
  2130. ovfl: /* overflow scheme integer */
  2131. return SCM_BOOL_F;
  2132. }
  2133. SCM
  2134. scm_istr2int (char *str, long len, long radix)
  2135. {
  2136. size_t j;
  2137. register size_t k, blen = 1;
  2138. size_t i = 0;
  2139. int c;
  2140. SCM res;
  2141. register SCM_BIGDIG *ds;
  2142. register unsigned long t2;
  2143. if (0 >= len)
  2144. return SCM_BOOL_F; /* zero scm_length */
  2145. /* Short numbers we parse directly into an int, to avoid the overhead
  2146. of creating a bignum. */
  2147. if (len < 6)
  2148. return scm_small_istr2int (str, len, radix);
  2149. /* table[] is the number of bits used by each digit in the given base,
  2150. ie. log(base)/log(2). A scale factor of 25 is applied, so eg. base 8
  2151. has 75 for 3 bits per digit. When the number is not exact (any non
  2152. power-of-2 base) it's rounded up, ensuring the size calculated will be
  2153. no less than what's needed. Eg. 25*log(10)/log(2) is 83.04 which gets
  2154. rounded up to 84. The following spot of perl generates the table
  2155. use POSIX;
  2156. foreach $i (2 .. 16) {
  2157. print POSIX::ceil(log($i)/log(2)*25),", /","* $i *","/\n";
  2158. }
  2159. The factor 25 is more or less arbitrary, it gives enough precision and
  2160. is what the code had in the past for base 10. */
  2161. {
  2162. static const unsigned table[] = {
  2163. 25, /* 2 */
  2164. 40, /* 3 */
  2165. 50, /* 4 */
  2166. 59, /* 5 */
  2167. 65, /* 6 */
  2168. 71, /* 7 */
  2169. 75, /* 8 */
  2170. 80, /* 9 */
  2171. 84, /* 10 */
  2172. 87, /* 11 */
  2173. 90, /* 12 */
  2174. 93, /* 13 */
  2175. 96, /* 14 */
  2176. 98, /* 15 */
  2177. 100, /* 16 */
  2178. };
  2179. /* FIXME: What is sizeof(char) for? */
  2180. j = 1 + (table[radix-2] * len * sizeof (char)) / (SCM_BITSPERDIG * 25);
  2181. }
  2182. switch (str[0])
  2183. { /* leading sign */
  2184. case '-':
  2185. case '+':
  2186. if (++i == (unsigned) len)
  2187. return SCM_BOOL_F; /* bad if lone `+' or `-' */
  2188. }
  2189. res = scm_i_mkbig (j, '-' == str[0]);
  2190. ds = SCM_BDIGITS (res);
  2191. for (k = j; k--;)
  2192. ds[k] = 0;
  2193. do
  2194. {
  2195. switch (c = str[i++])
  2196. {
  2197. case DIGITS:
  2198. c = c - '0';
  2199. goto accumulate;
  2200. case 'A':
  2201. case 'B':
  2202. case 'C':
  2203. case 'D':
  2204. case 'E':
  2205. case 'F':
  2206. c = c - 'A' + 10;
  2207. goto accumulate;
  2208. case 'a':
  2209. case 'b':
  2210. case 'c':
  2211. case 'd':
  2212. case 'e':
  2213. case 'f':
  2214. c = c - 'a' + 10;
  2215. accumulate:
  2216. if (c >= radix)
  2217. return SCM_BOOL_F; /* bad digit for radix */
  2218. k = 0;
  2219. t2 = c;
  2220. moretodo:
  2221. while (k < blen)
  2222. {
  2223. /* printf ("k = %d, blen = %d, t2 = %ld, ds[k] = %d\n", k, blen, t2, ds[k]); */
  2224. t2 += ds[k] * radix;
  2225. ds[k++] = SCM_BIGLO (t2);
  2226. t2 = SCM_BIGDN (t2);
  2227. }
  2228. if (t2)
  2229. {
  2230. if (blen >= j)
  2231. scm_num_overflow ("bignum");
  2232. blen++;
  2233. goto moretodo;
  2234. }
  2235. break;
  2236. default:
  2237. return SCM_BOOL_F; /* not a digit */
  2238. }
  2239. }
  2240. while (i < (unsigned) len);
  2241. if (blen * SCM_BITSPERDIG / SCM_CHAR_BIT <= sizeof (SCM))
  2242. if (SCM_INUMP (res = scm_i_big2inum (res, blen)))
  2243. return res;
  2244. if (j == blen)
  2245. return res;
  2246. return scm_i_adjbig (res, blen);
  2247. }
  2248. SCM
  2249. scm_istr2flo (char *str, long len, long radix)
  2250. {
  2251. register int c, i = 0;
  2252. double lead_sgn;
  2253. double res = 0.0, tmp = 0.0;
  2254. int flg = 0;
  2255. int point = 0;
  2256. SCM second;
  2257. if (i >= len)
  2258. return SCM_BOOL_F; /* zero scm_length */
  2259. switch (*str)
  2260. { /* leading sign */
  2261. case '-':
  2262. lead_sgn = -1.0;
  2263. i++;
  2264. break;
  2265. case '+':
  2266. lead_sgn = 1.0;
  2267. i++;
  2268. break;
  2269. default:
  2270. lead_sgn = 0.0;
  2271. }
  2272. if (i == len)
  2273. return SCM_BOOL_F; /* bad if lone `+' or `-' */
  2274. if (str[i] == 'i' || str[i] == 'I')
  2275. { /* handle `+i' and `-i' */
  2276. if (lead_sgn == 0.0)
  2277. return SCM_BOOL_F; /* must have leading sign */
  2278. if (++i < len)
  2279. return SCM_BOOL_F; /* `i' not last character */
  2280. return scm_make_complex (0.0, lead_sgn);
  2281. }
  2282. do
  2283. { /* check initial digits */
  2284. switch (c = str[i])
  2285. {
  2286. case DIGITS:
  2287. c = c - '0';
  2288. goto accum1;
  2289. case 'D':
  2290. case 'E':
  2291. case 'F':
  2292. if (radix == 10)
  2293. goto out1; /* must be exponent */
  2294. case 'A':
  2295. case 'B':
  2296. case 'C':
  2297. c = c - 'A' + 10;
  2298. goto accum1;
  2299. case 'd':
  2300. case 'e':
  2301. case 'f':
  2302. if (radix == 10)
  2303. goto out1;
  2304. case 'a':
  2305. case 'b':
  2306. case 'c':
  2307. c = c - 'a' + 10;
  2308. accum1:
  2309. if (c >= radix)
  2310. return SCM_BOOL_F; /* bad digit for radix */
  2311. res = res * radix + c;
  2312. flg = 1; /* res is valid */
  2313. break;
  2314. default:
  2315. goto out1;
  2316. }
  2317. }
  2318. while (++i < len);
  2319. out1:
  2320. /* if true, then we did see a digit above, and res is valid */
  2321. if (i == len)
  2322. goto done;
  2323. /* By here, must have seen a digit,
  2324. or must have next char be a `.' with radix==10 */
  2325. if (!flg)
  2326. if (!(str[i] == '.' && radix == 10))
  2327. return SCM_BOOL_F;
  2328. while (str[i] == '#')
  2329. { /* optional sharps */
  2330. res *= radix;
  2331. if (++i == len)
  2332. goto done;
  2333. }
  2334. if (str[i] == '/')
  2335. {
  2336. while (++i < len)
  2337. {
  2338. switch (c = str[i])
  2339. {
  2340. case DIGITS:
  2341. c = c - '0';
  2342. goto accum2;
  2343. case 'A':
  2344. case 'B':
  2345. case 'C':
  2346. case 'D':
  2347. case 'E':
  2348. case 'F':
  2349. c = c - 'A' + 10;
  2350. goto accum2;
  2351. case 'a':
  2352. case 'b':
  2353. case 'c':
  2354. case 'd':
  2355. case 'e':
  2356. case 'f':
  2357. c = c - 'a' + 10;
  2358. accum2:
  2359. if (c >= radix)
  2360. return SCM_BOOL_F;
  2361. tmp = tmp * radix + c;
  2362. break;
  2363. default:
  2364. goto out2;
  2365. }
  2366. }
  2367. out2:
  2368. if (tmp == 0.0)
  2369. return SCM_BOOL_F; /* `slash zero' not allowed */
  2370. if (i < len)
  2371. while (str[i] == '#')
  2372. { /* optional sharps */
  2373. tmp *= radix;
  2374. if (++i == len)
  2375. break;
  2376. }
  2377. res /= tmp;
  2378. goto done;
  2379. }
  2380. if (str[i] == '.')
  2381. { /* decimal point notation */
  2382. if (radix != 10)
  2383. return SCM_BOOL_F; /* must be radix 10 */
  2384. while (++i < len)
  2385. {
  2386. switch (c = str[i])
  2387. {
  2388. case DIGITS:
  2389. point--;
  2390. res = res * 10.0 + c - '0';
  2391. flg = 1;
  2392. break;
  2393. default:
  2394. goto out3;
  2395. }
  2396. }
  2397. out3:
  2398. if (!flg)
  2399. return SCM_BOOL_F; /* no digits before or after decimal point */
  2400. if (i == len)
  2401. goto adjust;
  2402. while (str[i] == '#')
  2403. { /* ignore remaining sharps */
  2404. if (++i == len)
  2405. goto adjust;
  2406. }
  2407. }
  2408. switch (str[i])
  2409. { /* exponent */
  2410. case 'd':
  2411. case 'D':
  2412. case 'e':
  2413. case 'E':
  2414. case 'f':
  2415. case 'F':
  2416. case 'l':
  2417. case 'L':
  2418. case 's':
  2419. case 'S':
  2420. {
  2421. int expsgn = 1, expon = 0;
  2422. if (radix != 10)
  2423. return SCM_BOOL_F; /* only in radix 10 */
  2424. if (++i == len)
  2425. return SCM_BOOL_F; /* bad exponent */
  2426. switch (str[i])
  2427. {
  2428. case '-':
  2429. expsgn = (-1);
  2430. case '+':
  2431. if (++i == len)
  2432. return SCM_BOOL_F; /* bad exponent */
  2433. }
  2434. if (str[i] < '0' || str[i] > '9')
  2435. return SCM_BOOL_F; /* bad exponent */
  2436. do
  2437. {
  2438. switch (c = str[i])
  2439. {
  2440. case DIGITS:
  2441. expon = expon * 10 + c - '0';
  2442. if (expon > SCM_MAXEXP)
  2443. scm_out_of_range ("string->number", SCM_MAKINUM (expon));
  2444. break;
  2445. default:
  2446. goto out4;
  2447. }
  2448. }
  2449. while (++i < len);
  2450. out4:
  2451. point += expsgn * expon;
  2452. }
  2453. }
  2454. adjust:
  2455. if (point >= 0)
  2456. while (point--)
  2457. res *= 10.0;
  2458. else
  2459. #ifdef _UNICOS
  2460. while (point++)
  2461. res *= 0.1;
  2462. #else
  2463. while (point++)
  2464. res /= 10.0;
  2465. #endif
  2466. done:
  2467. /* at this point, we have a legitimate floating point result */
  2468. if (lead_sgn == -1.0)
  2469. res = -res;
  2470. if (i == len)
  2471. return scm_make_real (res);
  2472. if (str[i] == 'i' || str[i] == 'I')
  2473. { /* pure imaginary number */
  2474. if (lead_sgn == 0.0)
  2475. return SCM_BOOL_F; /* must have leading sign */
  2476. if (++i < len)
  2477. return SCM_BOOL_F; /* `i' not last character */
  2478. return scm_make_complex (0.0, res);
  2479. }
  2480. switch (str[i++])
  2481. {
  2482. case '-':
  2483. lead_sgn = -1.0;
  2484. break;
  2485. case '+':
  2486. lead_sgn = 1.0;
  2487. break;
  2488. case '@':
  2489. { /* polar input for complex number */
  2490. /* get a `real' for scm_angle */
  2491. second = scm_istr2flo (&str[i], (long) (len - i), radix);
  2492. if (!SCM_INEXACTP (second))
  2493. return SCM_BOOL_F; /* not `real' */
  2494. if (SCM_SLOPPY_COMPLEXP (second))
  2495. return SCM_BOOL_F; /* not `real' */
  2496. tmp = SCM_REAL_VALUE (second);
  2497. return scm_make_complex (res * cos (tmp), res * sin (tmp));
  2498. }
  2499. default:
  2500. return SCM_BOOL_F;
  2501. }
  2502. /* at this point, last char must be `i' */
  2503. if (str[len - 1] != 'i' && str[len - 1] != 'I')
  2504. return SCM_BOOL_F;
  2505. /* handles `x+i' and `x-i' */
  2506. if (i == (len - 1))
  2507. return scm_make_complex (res, lead_sgn);
  2508. /* get a `ureal' for complex part */
  2509. second = scm_istr2flo (&str[i], (long) ((len - i) - 1), radix);
  2510. if (!SCM_INEXACTP (second))
  2511. return SCM_BOOL_F; /* not `ureal' */
  2512. if (SCM_SLOPPY_COMPLEXP (second))
  2513. return SCM_BOOL_F; /* not `ureal' */
  2514. tmp = SCM_REAL_VALUE (second);
  2515. if (tmp < 0.0)
  2516. return SCM_BOOL_F; /* not `ureal' */
  2517. return scm_make_complex (res, (lead_sgn * tmp));
  2518. }
  2519. SCM
  2520. scm_istring2number (char *str, long len, long radix)
  2521. {
  2522. int i = 0;
  2523. char ex = 0;
  2524. char ex_p = 0, rx_p = 0; /* Only allow 1 exactness and 1 radix prefix */
  2525. SCM res;
  2526. if (len == 1)
  2527. if (*str == '+' || *str == '-') /* Catches lone `+' and `-' for speed */
  2528. return SCM_BOOL_F;
  2529. while ((len - i) >= 2 && str[i] == '#' && ++i)
  2530. switch (str[i++])
  2531. {
  2532. case 'b':
  2533. case 'B':
  2534. if (rx_p++)
  2535. return SCM_BOOL_F;
  2536. radix = 2;
  2537. break;
  2538. case 'o':
  2539. case 'O':
  2540. if (rx_p++)
  2541. return SCM_BOOL_F;
  2542. radix = 8;
  2543. break;
  2544. case 'd':
  2545. case 'D':
  2546. if (rx_p++)
  2547. return SCM_BOOL_F;
  2548. radix = 10;
  2549. break;
  2550. case 'x':
  2551. case 'X':
  2552. if (rx_p++)
  2553. return SCM_BOOL_F;
  2554. radix = 16;
  2555. break;
  2556. case 'i':
  2557. case 'I':
  2558. if (ex_p++)
  2559. return SCM_BOOL_F;
  2560. ex = 2;
  2561. break;
  2562. case 'e':
  2563. case 'E':
  2564. if (ex_p++)
  2565. return SCM_BOOL_F;
  2566. ex = 1;
  2567. break;
  2568. default:
  2569. return SCM_BOOL_F;
  2570. }
  2571. switch (ex)
  2572. {
  2573. case 1:
  2574. return scm_istr2int (&str[i], len - i, radix);
  2575. case 0:
  2576. res = scm_istr2int (&str[i], len - i, radix);
  2577. if (!SCM_FALSEP (res))
  2578. return res;
  2579. case 2:
  2580. return scm_istr2flo (&str[i], len - i, radix);
  2581. }
  2582. return SCM_BOOL_F;
  2583. }
  2584. SCM_DEFINE (scm_string_to_number, "string->number", 1, 1, 0,
  2585. (SCM string, SCM radix),
  2586. "Return a number of the maximally precise representation\n"
  2587. "expressed by the given @var{string}. @var{radix} must be an\n"
  2588. "exact integer, either 2, 8, 10, or 16. If supplied, @var{radix}\n"
  2589. "is a default radix that may be overridden by an explicit radix\n"
  2590. "prefix in @var{string} (e.g. \"#o177\"). If @var{radix} is not\n"
  2591. "supplied, then the default radix is 10. If string is not a\n"
  2592. "syntactically valid notation for a number, then\n"
  2593. "@code{string->number} returns @code{#f}.")
  2594. #define FUNC_NAME s_scm_string_to_number
  2595. {
  2596. SCM answer;
  2597. int base;
  2598. SCM_VALIDATE_STRING (1, string);
  2599. SCM_VALIDATE_INUM_MIN_DEF_COPY (2,radix,2,10,base);
  2600. answer = scm_istring2number (SCM_STRING_CHARS (string),
  2601. SCM_STRING_LENGTH (string),
  2602. base);
  2603. return scm_return_first (answer, string);
  2604. }
  2605. #undef FUNC_NAME
  2606. /*** END strs->nums ***/
  2607. SCM
  2608. scm_make_real (double x)
  2609. {
  2610. SCM z;
  2611. SCM_NEWCELL2 (z);
  2612. SCM_SET_CELL_TYPE (z, scm_tc16_real);
  2613. SCM_REAL_VALUE (z) = x;
  2614. return z;
  2615. }
  2616. SCM
  2617. scm_make_complex (double x, double y)
  2618. {
  2619. if (y == 0.0) {
  2620. return scm_make_real (x);
  2621. } else {
  2622. SCM z;
  2623. SCM_NEWSMOB (z, scm_tc16_complex, scm_must_malloc (2L * sizeof (double), "complex"));
  2624. SCM_COMPLEX_REAL (z) = x;
  2625. SCM_COMPLEX_IMAG (z) = y;
  2626. return z;
  2627. }
  2628. }
  2629. SCM
  2630. scm_bigequal (SCM x, SCM y)
  2631. {
  2632. #ifdef SCM_BIGDIG
  2633. if (0 == scm_bigcomp (x, y))
  2634. return SCM_BOOL_T;
  2635. #endif
  2636. return SCM_BOOL_F;
  2637. }
  2638. SCM
  2639. scm_real_equalp (SCM x, SCM y)
  2640. {
  2641. return SCM_BOOL (SCM_REAL_VALUE (x) == SCM_REAL_VALUE (y));
  2642. }
  2643. SCM
  2644. scm_complex_equalp (SCM x, SCM y)
  2645. {
  2646. return SCM_BOOL (SCM_COMPLEX_REAL (x) == SCM_COMPLEX_REAL (y)
  2647. && SCM_COMPLEX_IMAG (x) == SCM_COMPLEX_IMAG (y));
  2648. }
  2649. SCM_REGISTER_PROC (s_number_p, "number?", 1, 0, 0, scm_number_p);
  2650. /* "Return @code{#t} if @var{x} is a number, @code{#f}\n"
  2651. * "else. Note that the sets of complex, real, rational and\n"
  2652. * "integer values form subsets of the set of numbers, i. e. the\n"
  2653. * "predicate will be fulfilled for any number."
  2654. */
  2655. SCM_DEFINE (scm_number_p, "complex?", 1, 0, 0,
  2656. (SCM x),
  2657. "Return @code{#t} if @var{x} is a complex number, @code{#f}\n"
  2658. "otherwise. Note that the sets of real, rational and integer\n"
  2659. "values form subsets of the set of complex numbers, i. e. the\n"
  2660. "predicate will also be fulfilled if @var{x} is a real,\n"
  2661. "rational or integer number.")
  2662. #define FUNC_NAME s_scm_number_p
  2663. {
  2664. return SCM_BOOL (SCM_NUMBERP (x));
  2665. }
  2666. #undef FUNC_NAME
  2667. SCM_REGISTER_PROC (s_real_p, "real?", 1, 0, 0, scm_real_p);
  2668. /* "Return @code{#t} if @var{x} is a real number, @code{#f} else.\n"
  2669. * "Note that the sets of integer and rational values form a subset\n"
  2670. * "of the set of real numbers, i. e. the predicate will also\n"
  2671. * "be fulfilled if @var{x} is an integer or a rational number."
  2672. */
  2673. SCM_DEFINE (scm_real_p, "rational?", 1, 0, 0,
  2674. (SCM x),
  2675. "Return @code{#t} if @var{x} is a rational number, @code{#f}\n"
  2676. "otherwise. Note that the set of integer values forms a subset of\n"
  2677. "the set of rational numbers, i. e. the predicate will also be\n"
  2678. "fulfilled if @var{x} is an integer number. Real numbers\n"
  2679. "will also satisfy this predicate, because of their limited\n"
  2680. "precision.")
  2681. #define FUNC_NAME s_scm_real_p
  2682. {
  2683. if (SCM_INUMP (x)) {
  2684. return SCM_BOOL_T;
  2685. } else if (SCM_IMP (x)) {
  2686. return SCM_BOOL_F;
  2687. } else if (SCM_SLOPPY_REALP (x)) {
  2688. return SCM_BOOL_T;
  2689. } else if (SCM_BIGP (x)) {
  2690. return SCM_BOOL_T;
  2691. } else {
  2692. return SCM_BOOL_F;
  2693. }
  2694. }
  2695. #undef FUNC_NAME
  2696. SCM_DEFINE (scm_integer_p, "integer?", 1, 0, 0,
  2697. (SCM x),
  2698. "Return @code{#t} if @var{x} is an integer number, @code{#f}\n"
  2699. "else.")
  2700. #define FUNC_NAME s_scm_integer_p
  2701. {
  2702. double r;
  2703. if (SCM_INUMP (x))
  2704. return SCM_BOOL_T;
  2705. if (SCM_IMP (x))
  2706. return SCM_BOOL_F;
  2707. if (SCM_BIGP (x))
  2708. return SCM_BOOL_T;
  2709. if (!SCM_SLOPPY_INEXACTP (x))
  2710. return SCM_BOOL_F;
  2711. if (SCM_SLOPPY_COMPLEXP (x))
  2712. return SCM_BOOL_F;
  2713. r = SCM_REAL_VALUE (x);
  2714. if (r == floor (r))
  2715. return SCM_BOOL_T;
  2716. return SCM_BOOL_F;
  2717. }
  2718. #undef FUNC_NAME
  2719. SCM_DEFINE (scm_inexact_p, "inexact?", 1, 0, 0,
  2720. (SCM x),
  2721. "Return @code{#t} if @var{x} is an inexact number, @code{#f}\n"
  2722. "else.")
  2723. #define FUNC_NAME s_scm_inexact_p
  2724. {
  2725. return SCM_BOOL (SCM_INEXACTP (x));
  2726. }
  2727. #undef FUNC_NAME
  2728. SCM_GPROC1 (s_eq_p, "=", scm_tc7_rpsubr, scm_num_eq_p, g_eq_p);
  2729. /* "Return @code{#t} if all parameters are numerically equal." */
  2730. SCM
  2731. scm_num_eq_p (SCM x, SCM y)
  2732. {
  2733. if (SCM_INUMP (x)) {
  2734. long xx = SCM_INUM (x);
  2735. if (SCM_INUMP (y)) {
  2736. long yy = SCM_INUM (y);
  2737. return SCM_BOOL (xx == yy);
  2738. } else if (SCM_BIGP (y)) {
  2739. return SCM_BOOL_F;
  2740. } else if (SCM_REALP (y)) {
  2741. return SCM_BOOL ((double) xx == SCM_REAL_VALUE (y));
  2742. } else if (SCM_COMPLEXP (y)) {
  2743. return SCM_BOOL (((double) xx == SCM_COMPLEX_REAL (y))
  2744. && (0.0 == SCM_COMPLEX_IMAG (y)));
  2745. } else {
  2746. SCM_WTA_DISPATCH_2 (g_eq_p, x, y, SCM_ARGn, s_eq_p);
  2747. }
  2748. } else if (SCM_BIGP (x)) {
  2749. if (SCM_INUMP (y)) {
  2750. return SCM_BOOL_F;
  2751. } else if (SCM_BIGP (y)) {
  2752. return SCM_BOOL (0 == scm_bigcomp (x, y));
  2753. } else if (SCM_REALP (y)) {
  2754. return SCM_BOOL (scm_i_big2dbl (x) == SCM_REAL_VALUE (y));
  2755. } else if (SCM_COMPLEXP (y)) {
  2756. return SCM_BOOL ((scm_i_big2dbl (x) == SCM_COMPLEX_REAL (y))
  2757. && (0.0 == SCM_COMPLEX_IMAG (y)));
  2758. } else {
  2759. SCM_WTA_DISPATCH_2 (g_eq_p, x, y, SCM_ARGn, s_eq_p);
  2760. }
  2761. } else if (SCM_REALP (x)) {
  2762. if (SCM_INUMP (y)) {
  2763. return SCM_BOOL (SCM_REAL_VALUE (x) == (double) SCM_INUM (y));
  2764. } else if (SCM_BIGP (y)) {
  2765. return SCM_BOOL (SCM_REAL_VALUE (x) == scm_i_big2dbl (y));
  2766. } else if (SCM_REALP (y)) {
  2767. return SCM_BOOL (SCM_REAL_VALUE (x) == SCM_REAL_VALUE (y));
  2768. } else if (SCM_COMPLEXP (y)) {
  2769. return SCM_BOOL ((SCM_REAL_VALUE (x) == SCM_COMPLEX_REAL (y))
  2770. && (0.0 == SCM_COMPLEX_IMAG (y)));
  2771. } else {
  2772. SCM_WTA_DISPATCH_2 (g_eq_p, x, y, SCM_ARGn, s_eq_p);
  2773. }
  2774. } else if (SCM_COMPLEXP (x)) {
  2775. if (SCM_INUMP (y)) {
  2776. return SCM_BOOL ((SCM_COMPLEX_REAL (x) == (double) SCM_INUM (y))
  2777. && (SCM_COMPLEX_IMAG (x) == 0.0));
  2778. } else if (SCM_BIGP (y)) {
  2779. return SCM_BOOL ((SCM_COMPLEX_REAL (x) == scm_i_big2dbl (y))
  2780. && (SCM_COMPLEX_IMAG (x) == 0.0));
  2781. } else if (SCM_REALP (y)) {
  2782. return SCM_BOOL ((SCM_COMPLEX_REAL (x) == SCM_REAL_VALUE (y))
  2783. && (SCM_COMPLEX_IMAG (x) == 0.0));
  2784. } else if (SCM_COMPLEXP (y)) {
  2785. return SCM_BOOL ((SCM_COMPLEX_REAL (x) == SCM_COMPLEX_REAL (y))
  2786. && (SCM_COMPLEX_IMAG (x) == SCM_COMPLEX_IMAG (y)));
  2787. } else {
  2788. SCM_WTA_DISPATCH_2 (g_eq_p, x, y, SCM_ARGn, s_eq_p);
  2789. }
  2790. } else {
  2791. SCM_WTA_DISPATCH_2 (g_eq_p, x, y, SCM_ARG1, s_eq_p);
  2792. }
  2793. }
  2794. SCM_GPROC1 (s_less_p, "<", scm_tc7_rpsubr, scm_less_p, g_less_p);
  2795. /* "Return @code{#t} if the list of parameters is monotonically\n"
  2796. * "increasing."
  2797. */
  2798. SCM
  2799. scm_less_p (SCM x, SCM y)
  2800. {
  2801. if (SCM_INUMP (x)) {
  2802. long xx = SCM_INUM (x);
  2803. if (SCM_INUMP (y)) {
  2804. long yy = SCM_INUM (y);
  2805. return SCM_BOOL (xx < yy);
  2806. } else if (SCM_BIGP (y)) {
  2807. return SCM_BOOL (!SCM_BIGSIGN (y));
  2808. } else if (SCM_REALP (y)) {
  2809. return SCM_BOOL ((double) xx < SCM_REAL_VALUE (y));
  2810. } else {
  2811. SCM_WTA_DISPATCH_2 (g_less_p, x, y, SCM_ARGn, s_less_p);
  2812. }
  2813. } else if (SCM_BIGP (x)) {
  2814. if (SCM_INUMP (y)) {
  2815. return SCM_BOOL (SCM_BIGSIGN (x));
  2816. } else if (SCM_BIGP (y)) {
  2817. return SCM_BOOL (1 == scm_bigcomp (x, y));
  2818. } else if (SCM_REALP (y)) {
  2819. return SCM_BOOL (scm_i_big2dbl (x) < SCM_REAL_VALUE (y));
  2820. } else {
  2821. SCM_WTA_DISPATCH_2 (g_less_p, x, y, SCM_ARGn, s_less_p);
  2822. }
  2823. } else if (SCM_REALP (x)) {
  2824. if (SCM_INUMP (y)) {
  2825. return SCM_BOOL (SCM_REAL_VALUE (x) < (double) SCM_INUM (y));
  2826. } else if (SCM_BIGP (y)) {
  2827. return SCM_BOOL (SCM_REAL_VALUE (x) < scm_i_big2dbl (y));
  2828. } else if (SCM_REALP (y)) {
  2829. return SCM_BOOL (SCM_REAL_VALUE (x) < SCM_REAL_VALUE (y));
  2830. } else {
  2831. SCM_WTA_DISPATCH_2 (g_less_p, x, y, SCM_ARGn, s_less_p);
  2832. }
  2833. } else {
  2834. SCM_WTA_DISPATCH_2 (g_less_p, x, y, SCM_ARG1, s_less_p);
  2835. }
  2836. }
  2837. SCM_GPROC1 (s_scm_gr_p, ">", scm_tc7_rpsubr, scm_gr_p, g_gr_p);
  2838. /* "Return @code{#t} if the list of parameters is monotonically\n"
  2839. * "decreasing."
  2840. */
  2841. #define FUNC_NAME s_scm_gr_p
  2842. SCM
  2843. scm_gr_p (SCM x, SCM y)
  2844. {
  2845. if (!SCM_NUMBERP (x))
  2846. SCM_WTA_DISPATCH_2 (g_gr_p, x, y, SCM_ARG1, FUNC_NAME);
  2847. else if (!SCM_NUMBERP (y))
  2848. SCM_WTA_DISPATCH_2 (g_gr_p, x, y, SCM_ARG2, FUNC_NAME);
  2849. else
  2850. return scm_less_p (y, x);
  2851. }
  2852. #undef FUNC_NAME
  2853. SCM_GPROC1 (s_scm_leq_p, "<=", scm_tc7_rpsubr, scm_leq_p, g_leq_p);
  2854. /* "Return @code{#t} if the list of parameters is monotonically\n"
  2855. * "non-decreasing."
  2856. */
  2857. #define FUNC_NAME s_scm_leq_p
  2858. SCM
  2859. scm_leq_p (SCM x, SCM y)
  2860. {
  2861. if (!SCM_NUMBERP (x))
  2862. SCM_WTA_DISPATCH_2 (g_leq_p, x, y, SCM_ARG1, FUNC_NAME);
  2863. else if (!SCM_NUMBERP (y))
  2864. SCM_WTA_DISPATCH_2 (g_leq_p, x, y, SCM_ARG2, FUNC_NAME);
  2865. else
  2866. return SCM_BOOL_NOT (scm_less_p (y, x));
  2867. }
  2868. #undef FUNC_NAME
  2869. SCM_GPROC1 (s_scm_geq_p, ">=", scm_tc7_rpsubr, scm_geq_p, g_geq_p);
  2870. /* "Return @code{#t} if the list of parameters is monotonically\n"
  2871. * "non-increasing."
  2872. */
  2873. #define FUNC_NAME s_scm_geq_p
  2874. SCM
  2875. scm_geq_p (SCM x, SCM y)
  2876. {
  2877. if (!SCM_NUMBERP (x))
  2878. SCM_WTA_DISPATCH_2 (g_geq_p, x, y, SCM_ARG1, FUNC_NAME);
  2879. else if (!SCM_NUMBERP (y))
  2880. SCM_WTA_DISPATCH_2 (g_geq_p, x, y, SCM_ARG2, FUNC_NAME);
  2881. else
  2882. return SCM_BOOL_NOT (scm_less_p (x, y));
  2883. }
  2884. #undef FUNC_NAME
  2885. SCM_GPROC (s_zero_p, "zero?", 1, 0, 0, scm_zero_p, g_zero_p);
  2886. /* "Return @code{#t} if @var{z} is an exact or inexact number equal to\n"
  2887. * "zero."
  2888. */
  2889. SCM
  2890. scm_zero_p (SCM z)
  2891. {
  2892. if (SCM_INUMP (z)) {
  2893. return SCM_BOOL (SCM_EQ_P (z, SCM_INUM0));
  2894. } else if (SCM_BIGP (z)) {
  2895. return SCM_BOOL_F;
  2896. } else if (SCM_REALP (z)) {
  2897. return SCM_BOOL (SCM_REAL_VALUE (z) == 0.0);
  2898. } else if (SCM_COMPLEXP (z)) {
  2899. return SCM_BOOL (SCM_COMPLEX_REAL (z) == 0.0
  2900. && SCM_COMPLEX_IMAG (z) == 0.0);
  2901. } else {
  2902. SCM_WTA_DISPATCH_1 (g_zero_p, z, SCM_ARG1, s_zero_p);
  2903. }
  2904. }
  2905. SCM_GPROC (s_positive_p, "positive?", 1, 0, 0, scm_positive_p, g_positive_p);
  2906. /* "Return @code{#t} if @var{x} is an exact or inexact number greater than\n"
  2907. * "zero."
  2908. */
  2909. SCM
  2910. scm_positive_p (SCM x)
  2911. {
  2912. if (SCM_INUMP (x)) {
  2913. return SCM_BOOL (SCM_INUM (x) > 0);
  2914. } else if (SCM_BIGP (x)) {
  2915. return SCM_BOOL (!SCM_BIGSIGN (x));
  2916. } else if (SCM_REALP (x)) {
  2917. return SCM_BOOL(SCM_REAL_VALUE (x) > 0.0);
  2918. } else {
  2919. SCM_WTA_DISPATCH_1 (g_positive_p, x, SCM_ARG1, s_positive_p);
  2920. }
  2921. }
  2922. SCM_GPROC (s_negative_p, "negative?", 1, 0, 0, scm_negative_p, g_negative_p);
  2923. /* "Return @code{#t} if @var{x} is an exact or inexact number less than\n"
  2924. * "zero."
  2925. */
  2926. SCM
  2927. scm_negative_p (SCM x)
  2928. {
  2929. if (SCM_INUMP (x)) {
  2930. return SCM_BOOL (SCM_INUM (x) < 0);
  2931. } else if (SCM_BIGP (x)) {
  2932. return SCM_BOOL (SCM_BIGSIGN (x));
  2933. } else if (SCM_REALP (x)) {
  2934. return SCM_BOOL(SCM_REAL_VALUE (x) < 0.0);
  2935. } else {
  2936. SCM_WTA_DISPATCH_1 (g_negative_p, x, SCM_ARG1, s_negative_p);
  2937. }
  2938. }
  2939. SCM_GPROC1 (s_max, "max", scm_tc7_asubr, scm_max, g_max);
  2940. /* "Return the maximum of all parameter values."
  2941. */
  2942. SCM
  2943. scm_max (SCM x, SCM y)
  2944. {
  2945. if (SCM_UNBNDP (y)) {
  2946. if (SCM_UNBNDP (x)) {
  2947. SCM_WTA_DISPATCH_0 (g_max, s_max);
  2948. } else if (SCM_NUMBERP (x)) {
  2949. return x;
  2950. } else {
  2951. SCM_WTA_DISPATCH_1 (g_max, x, SCM_ARG1, s_max);
  2952. }
  2953. }
  2954. if (SCM_INUMP (x)) {
  2955. long xx = SCM_INUM (x);
  2956. if (SCM_INUMP (y)) {
  2957. long yy = SCM_INUM (y);
  2958. return (xx < yy) ? y : x;
  2959. } else if (SCM_BIGP (y)) {
  2960. return SCM_BIGSIGN (y) ? x : y;
  2961. } else if (SCM_REALP (y)) {
  2962. double z = xx;
  2963. return (z <= SCM_REAL_VALUE (y)) ? y : scm_make_real (z);
  2964. } else {
  2965. SCM_WTA_DISPATCH_2 (g_max, x, y, SCM_ARGn, s_max);
  2966. }
  2967. } else if (SCM_BIGP (x)) {
  2968. if (SCM_INUMP (y)) {
  2969. return SCM_BIGSIGN (x) ? y : x;
  2970. } else if (SCM_BIGP (y)) {
  2971. return (1 == scm_bigcomp (x, y)) ? y : x;
  2972. } else if (SCM_REALP (y)) {
  2973. double z = scm_i_big2dbl (x);
  2974. return (z <= SCM_REAL_VALUE (y)) ? y : scm_make_real (z);
  2975. } else {
  2976. SCM_WTA_DISPATCH_2 (g_max, x, y, SCM_ARGn, s_max);
  2977. }
  2978. } else if (SCM_REALP (x)) {
  2979. if (SCM_INUMP (y)) {
  2980. double z = SCM_INUM (y);
  2981. return (SCM_REAL_VALUE (x) < z) ? scm_make_real (z) : x;
  2982. } else if (SCM_BIGP (y)) {
  2983. double z = scm_i_big2dbl (y);
  2984. return (SCM_REAL_VALUE (x) < z) ? scm_make_real (z) : x;
  2985. } else if (SCM_REALP (y)) {
  2986. return (SCM_REAL_VALUE (x) < SCM_REAL_VALUE (y)) ? y : x;
  2987. } else {
  2988. SCM_WTA_DISPATCH_2 (g_max, x, y, SCM_ARGn, s_max);
  2989. }
  2990. } else {
  2991. SCM_WTA_DISPATCH_2 (g_max, x, y, SCM_ARG1, s_max);
  2992. }
  2993. }
  2994. SCM_GPROC1 (s_min, "min", scm_tc7_asubr, scm_min, g_min);
  2995. /* "Return the minium of all parameter values."
  2996. */
  2997. SCM
  2998. scm_min (SCM x, SCM y)
  2999. {
  3000. if (SCM_UNBNDP (y)) {
  3001. if (SCM_UNBNDP (x)) {
  3002. SCM_WTA_DISPATCH_0 (g_min, s_min);
  3003. } else if (SCM_NUMBERP (x)) {
  3004. return x;
  3005. } else {
  3006. SCM_WTA_DISPATCH_1 (g_min, x, SCM_ARG1, s_min);
  3007. }
  3008. }
  3009. if (SCM_INUMP (x)) {
  3010. long xx = SCM_INUM (x);
  3011. if (SCM_INUMP (y)) {
  3012. long yy = SCM_INUM (y);
  3013. return (xx < yy) ? x : y;
  3014. } else if (SCM_BIGP (y)) {
  3015. return SCM_BIGSIGN (y) ? y : x;
  3016. } else if (SCM_REALP (y)) {
  3017. double z = xx;
  3018. return (z < SCM_REAL_VALUE (y)) ? scm_make_real (z) : y;
  3019. } else {
  3020. SCM_WTA_DISPATCH_2 (g_min, x, y, SCM_ARGn, s_min);
  3021. }
  3022. } else if (SCM_BIGP (x)) {
  3023. if (SCM_INUMP (y)) {
  3024. return SCM_BIGSIGN (x) ? x : y;
  3025. } else if (SCM_BIGP (y)) {
  3026. return (-1 == scm_bigcomp (x, y)) ? y : x;
  3027. } else if (SCM_REALP (y)) {
  3028. double z = scm_i_big2dbl (x);
  3029. return (z < SCM_REAL_VALUE (y)) ? scm_make_real (z) : y;
  3030. } else {
  3031. SCM_WTA_DISPATCH_2 (g_min, x, y, SCM_ARGn, s_min);
  3032. }
  3033. } else if (SCM_REALP (x)) {
  3034. if (SCM_INUMP (y)) {
  3035. double z = SCM_INUM (y);
  3036. return (SCM_REAL_VALUE (x) <= z) ? x : scm_make_real (z);
  3037. } else if (SCM_BIGP (y)) {
  3038. double z = scm_i_big2dbl (y);
  3039. return (SCM_REAL_VALUE (x) <= z) ? x : scm_make_real (z);
  3040. } else if (SCM_REALP (y)) {
  3041. return (SCM_REAL_VALUE (x) < SCM_REAL_VALUE (y)) ? x : y;
  3042. } else {
  3043. SCM_WTA_DISPATCH_2 (g_min, x, y, SCM_ARGn, s_min);
  3044. }
  3045. } else {
  3046. SCM_WTA_DISPATCH_2 (g_min, x, y, SCM_ARG1, s_min);
  3047. }
  3048. }
  3049. SCM_GPROC1 (s_sum, "+", scm_tc7_asubr, scm_sum, g_sum);
  3050. /* "Return the sum of all parameter values. Return 0 if called without\n"
  3051. * "any parameters."
  3052. */
  3053. SCM
  3054. scm_sum (SCM x, SCM y)
  3055. {
  3056. if (SCM_UNBNDP (y)) {
  3057. if (SCM_UNBNDP (x)) {
  3058. return SCM_INUM0;
  3059. } else if (SCM_NUMBERP (x)) {
  3060. return x;
  3061. } else {
  3062. SCM_WTA_DISPATCH_1 (g_sum, x, SCM_ARG1, s_sum);
  3063. }
  3064. }
  3065. if (SCM_INUMP (x)) {
  3066. long int xx = SCM_INUM (x);
  3067. if (SCM_INUMP (y)) {
  3068. long int yy = SCM_INUM (y);
  3069. long int z = xx + yy;
  3070. if (SCM_FIXABLE (z)) {
  3071. return SCM_MAKINUM (z);
  3072. } else {
  3073. #ifdef SCM_BIGDIG
  3074. return scm_i_long2big (z);
  3075. #else /* SCM_BIGDIG */
  3076. return scm_make_real ((double) z);
  3077. #endif /* SCM_BIGDIG */
  3078. }
  3079. } else if (SCM_BIGP (y)) {
  3080. intbig:
  3081. {
  3082. long int xx = SCM_INUM (x);
  3083. #ifndef SCM_DIGSTOOBIG
  3084. long z = scm_pseudolong (xx);
  3085. return scm_addbig ((SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
  3086. (xx < 0) ? SCM_BIGSIGNFLAG : 0, y, 0);
  3087. #else /* SCM_DIGSTOOBIG */
  3088. SCM_BIGDIG zdigs [SCM_DIGSPERLONG];
  3089. scm_longdigs (xx, zdigs);
  3090. return scm_addbig (zdigs, SCM_DIGSPERLONG,
  3091. (xx < 0) ? SCM_BIGSIGNFLAG : 0, y, 0);
  3092. #endif /* SCM_DIGSTOOBIG */
  3093. }
  3094. } else if (SCM_REALP (y)) {
  3095. return scm_make_real (xx + SCM_REAL_VALUE (y));
  3096. } else if (SCM_COMPLEXP (y)) {
  3097. return scm_make_complex (xx + SCM_COMPLEX_REAL (y),
  3098. SCM_COMPLEX_IMAG (y));
  3099. } else {
  3100. SCM_WTA_DISPATCH_2 (g_sum, x, y, SCM_ARGn, s_sum);
  3101. }
  3102. } else if (SCM_BIGP (x)) {
  3103. if (SCM_INUMP (y)) {
  3104. SCM_SWAP (x, y);
  3105. goto intbig;
  3106. } else if (SCM_BIGP (y)) {
  3107. if (SCM_NUMDIGS (x) > SCM_NUMDIGS (y)) {
  3108. SCM_SWAP (x, y);
  3109. }
  3110. return scm_addbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
  3111. SCM_BIGSIGN (x), y, 0);
  3112. } else if (SCM_REALP (y)) {
  3113. return scm_make_real (scm_i_big2dbl (x) + SCM_REAL_VALUE (y));
  3114. } else if (SCM_COMPLEXP (y)) {
  3115. return scm_make_complex (scm_i_big2dbl (x) + SCM_COMPLEX_REAL (y),
  3116. SCM_COMPLEX_IMAG (y));
  3117. } else {
  3118. SCM_WTA_DISPATCH_2 (g_sum, x, y, SCM_ARGn, s_sum);
  3119. }
  3120. } else if (SCM_REALP (x)) {
  3121. if (SCM_INUMP (y)) {
  3122. return scm_make_real (SCM_REAL_VALUE (x) + SCM_INUM (y));
  3123. } else if (SCM_BIGP (y)) {
  3124. return scm_make_real (SCM_REAL_VALUE (x) + scm_i_big2dbl (y));
  3125. } else if (SCM_REALP (y)) {
  3126. return scm_make_real (SCM_REAL_VALUE (x) + SCM_REAL_VALUE (y));
  3127. } else if (SCM_COMPLEXP (y)) {
  3128. return scm_make_complex (SCM_REAL_VALUE (x) + SCM_COMPLEX_REAL (y),
  3129. SCM_COMPLEX_IMAG (y));
  3130. } else {
  3131. SCM_WTA_DISPATCH_2 (g_sum, x, y, SCM_ARGn, s_sum);
  3132. }
  3133. } else if (SCM_COMPLEXP (x)) {
  3134. if (SCM_INUMP (y)) {
  3135. return scm_make_complex (SCM_COMPLEX_REAL (x) + SCM_INUM (y),
  3136. SCM_COMPLEX_IMAG (x));
  3137. } else if (SCM_BIGP (y)) {
  3138. return scm_make_complex (SCM_COMPLEX_REAL (x) + scm_i_big2dbl (y),
  3139. SCM_COMPLEX_IMAG (x));
  3140. } else if (SCM_REALP (y)) {
  3141. return scm_make_complex (SCM_COMPLEX_REAL (x) + SCM_REAL_VALUE (y),
  3142. SCM_COMPLEX_IMAG (x));
  3143. } else if (SCM_COMPLEXP (y)) {
  3144. return scm_make_complex (SCM_COMPLEX_REAL (x) + SCM_COMPLEX_REAL (y),
  3145. SCM_COMPLEX_IMAG (x) + SCM_COMPLEX_IMAG (y));
  3146. } else {
  3147. SCM_WTA_DISPATCH_2 (g_sum, x, y, SCM_ARGn, s_sum);
  3148. }
  3149. } else {
  3150. SCM_WTA_DISPATCH_2 (g_sum, x, y, SCM_ARG1, s_sum);
  3151. }
  3152. }
  3153. SCM_GPROC1 (s_difference, "-", scm_tc7_asubr, scm_difference, g_difference);
  3154. /* If called with one argument @var{z1}, -@var{z1} returned. Otherwise
  3155. * the sum of all but the first argument are subtracted from the first
  3156. * argument. */
  3157. #define FUNC_NAME s_difference
  3158. SCM
  3159. scm_difference (SCM x, SCM y)
  3160. {
  3161. if (SCM_UNBNDP (y)) {
  3162. if (SCM_UNBNDP (x)) {
  3163. SCM_WTA_DISPATCH_0 (g_difference, s_difference);
  3164. } else if (SCM_INUMP (x)) {
  3165. long xx = -SCM_INUM (x);
  3166. if (SCM_FIXABLE (xx)) {
  3167. return SCM_MAKINUM (xx);
  3168. } else {
  3169. #ifdef SCM_BIGDIG
  3170. return scm_i_long2big (xx);
  3171. #else
  3172. return scm_make_real ((double) xx);
  3173. #endif
  3174. }
  3175. } else if (SCM_BIGP (x)) {
  3176. SCM z = scm_i_copybig (x, !SCM_BIGSIGN (x));
  3177. unsigned int digs = SCM_NUMDIGS (z);
  3178. unsigned int size = digs * SCM_BITSPERDIG / SCM_CHAR_BIT;
  3179. return size <= sizeof (SCM) ? scm_i_big2inum (z, digs) : z;
  3180. } else if (SCM_REALP (x)) {
  3181. return scm_make_real (-SCM_REAL_VALUE (x));
  3182. } else if (SCM_COMPLEXP (x)) {
  3183. return scm_make_complex (-SCM_COMPLEX_REAL (x), -SCM_COMPLEX_IMAG (x));
  3184. } else {
  3185. SCM_WTA_DISPATCH_1 (g_difference, x, SCM_ARG1, s_difference);
  3186. }
  3187. }
  3188. if (SCM_INUMP (x)) {
  3189. long int xx = SCM_INUM (x);
  3190. if (SCM_INUMP (y)) {
  3191. long int yy = SCM_INUM (y);
  3192. long int z = xx - yy;
  3193. if (SCM_FIXABLE (z)) {
  3194. return SCM_MAKINUM (z);
  3195. } else {
  3196. #ifdef SCM_BIGDIG
  3197. return scm_i_long2big (z);
  3198. #else
  3199. return scm_make_real ((double) z);
  3200. #endif
  3201. }
  3202. } else if (SCM_BIGP (y)) {
  3203. #ifndef SCM_DIGSTOOBIG
  3204. long z = scm_pseudolong (xx);
  3205. return scm_addbig ((SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
  3206. (xx < 0) ? SCM_BIGSIGNFLAG : 0, y, SCM_BIGSIGNFLAG);
  3207. #else
  3208. SCM_BIGDIG zdigs [SCM_DIGSPERLONG];
  3209. scm_longdigs (xx, zdigs);
  3210. return scm_addbig (zdigs, SCM_DIGSPERLONG,
  3211. (xx < 0) ? SCM_BIGSIGNFLAG : 0, y, SCM_BIGSIGNFLAG);
  3212. #endif
  3213. } else if (SCM_REALP (y)) {
  3214. return scm_make_real (xx - SCM_REAL_VALUE (y));
  3215. } else if (SCM_COMPLEXP (y)) {
  3216. return scm_make_complex (xx - SCM_COMPLEX_REAL (y),
  3217. -SCM_COMPLEX_IMAG (y));
  3218. } else {
  3219. SCM_WTA_DISPATCH_2 (g_difference, x, y, SCM_ARGn, s_difference);
  3220. }
  3221. } else if (SCM_BIGP (x)) {
  3222. if (SCM_INUMP (y)) {
  3223. long int yy = SCM_INUM (y);
  3224. #ifndef SCM_DIGSTOOBIG
  3225. long z = scm_pseudolong (yy);
  3226. return scm_addbig ((SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
  3227. (yy < 0) ? 0 : SCM_BIGSIGNFLAG, x, 0);
  3228. #else
  3229. SCM_BIGDIG zdigs [SCM_DIGSPERLONG];
  3230. scm_longdigs (yy, zdigs);
  3231. return scm_addbig (zdigs, SCM_DIGSPERLONG,
  3232. (yy < 0) ? 0 : SCM_BIGSIGNFLAG, x, 0);
  3233. #endif
  3234. } else if (SCM_BIGP (y)) {
  3235. return (SCM_NUMDIGS (x) < SCM_NUMDIGS (y))
  3236. ? scm_addbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
  3237. SCM_BIGSIGN (x), y, SCM_BIGSIGNFLAG)
  3238. : scm_addbig (SCM_BDIGITS (y), SCM_NUMDIGS (y),
  3239. SCM_BIGSIGN (y) ^ SCM_BIGSIGNFLAG, x, 0);
  3240. } else if (SCM_REALP (y)) {
  3241. return scm_make_real (scm_i_big2dbl (x) - SCM_REAL_VALUE (y));
  3242. } else if (SCM_COMPLEXP (y)) {
  3243. return scm_make_complex (scm_i_big2dbl (x) - SCM_COMPLEX_REAL (y),
  3244. - SCM_COMPLEX_IMAG (y));
  3245. } else {
  3246. SCM_WTA_DISPATCH_2 (g_difference, x, y, SCM_ARGn, s_difference);
  3247. }
  3248. } else if (SCM_REALP (x)) {
  3249. if (SCM_INUMP (y)) {
  3250. return scm_make_real (SCM_REAL_VALUE (x) - SCM_INUM (y));
  3251. } else if (SCM_BIGP (y)) {
  3252. return scm_make_real (SCM_REAL_VALUE (x) - scm_i_big2dbl (y));
  3253. } else if (SCM_REALP (y)) {
  3254. return scm_make_real (SCM_REAL_VALUE (x) - SCM_REAL_VALUE (y));
  3255. } else if (SCM_COMPLEXP (y)) {
  3256. return scm_make_complex (SCM_REAL_VALUE (x) - SCM_COMPLEX_REAL (y),
  3257. -SCM_COMPLEX_IMAG (y));
  3258. } else {
  3259. SCM_WTA_DISPATCH_2 (g_difference, x, y, SCM_ARGn, s_difference);
  3260. }
  3261. } else if (SCM_COMPLEXP (x)) {
  3262. if (SCM_INUMP (y)) {
  3263. return scm_make_complex (SCM_COMPLEX_REAL (x) - SCM_INUM (y),
  3264. SCM_COMPLEX_IMAG (x));
  3265. } else if (SCM_BIGP (y)) {
  3266. return scm_make_complex (SCM_COMPLEX_REAL (x) - scm_i_big2dbl (y),
  3267. SCM_COMPLEX_IMAG (x));
  3268. } else if (SCM_REALP (y)) {
  3269. return scm_make_complex (SCM_COMPLEX_REAL (x) - SCM_REAL_VALUE (y),
  3270. SCM_COMPLEX_IMAG (x));
  3271. } else if (SCM_COMPLEXP (y)) {
  3272. return scm_make_complex (SCM_COMPLEX_REAL (x) - SCM_COMPLEX_REAL (y),
  3273. SCM_COMPLEX_IMAG (x) - SCM_COMPLEX_IMAG (y));
  3274. } else {
  3275. SCM_WTA_DISPATCH_2 (g_difference, x, y, SCM_ARGn, s_difference);
  3276. }
  3277. } else {
  3278. SCM_WTA_DISPATCH_2 (g_difference, x, y, SCM_ARG1, s_difference);
  3279. }
  3280. }
  3281. #undef FUNC_NAME
  3282. SCM_GPROC1 (s_product, "*", scm_tc7_asubr, scm_product, g_product);
  3283. /* "Return the product of all arguments. If called without arguments,\n"
  3284. * "1 is returned."
  3285. */
  3286. SCM
  3287. scm_product (SCM x, SCM y)
  3288. {
  3289. if (SCM_UNBNDP (y)) {
  3290. if (SCM_UNBNDP (x)) {
  3291. return SCM_MAKINUM (1L);
  3292. } else if (SCM_NUMBERP (x)) {
  3293. return x;
  3294. } else {
  3295. SCM_WTA_DISPATCH_1 (g_product, x, SCM_ARG1, s_product);
  3296. }
  3297. }
  3298. if (SCM_INUMP (x)) {
  3299. long xx;
  3300. intbig:
  3301. xx = SCM_INUM (x);
  3302. if (xx == 0) {
  3303. return x;
  3304. } else if (xx == 1) {
  3305. return y;
  3306. }
  3307. if (SCM_INUMP (y)) {
  3308. long yy = SCM_INUM (y);
  3309. long kk = xx * yy;
  3310. SCM k = SCM_MAKINUM (kk);
  3311. if (kk != SCM_INUM (k) || kk / xx != yy) {
  3312. #ifdef SCM_BIGDIG
  3313. int sgn = (xx < 0) ^ (yy < 0);
  3314. #ifndef SCM_DIGSTOOBIG
  3315. long i = scm_pseudolong (xx);
  3316. long j = scm_pseudolong (yy);
  3317. return scm_mulbig ((SCM_BIGDIG *) & i, SCM_DIGSPERLONG,
  3318. (SCM_BIGDIG *) & j, SCM_DIGSPERLONG, sgn);
  3319. #else /* SCM_DIGSTOOBIG */
  3320. SCM_BIGDIG xdigs [SCM_DIGSPERLONG];
  3321. SCM_BIGDIG ydigs [SCM_DIGSPERLONG];
  3322. scm_longdigs (xx, xdigs);
  3323. scm_longdigs (yy, ydigs);
  3324. return scm_mulbig (xdigs, SCM_DIGSPERLONG,
  3325. ydigs, SCM_DIGSPERLONG,
  3326. sgn);
  3327. #endif
  3328. #else
  3329. return scm_make_real (((double) xx) * ((double) yy));
  3330. #endif
  3331. } else {
  3332. return k;
  3333. }
  3334. } else if (SCM_BIGP (y)) {
  3335. #ifndef SCM_DIGSTOOBIG
  3336. long z = scm_pseudolong (xx);
  3337. return scm_mulbig ((SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
  3338. SCM_BDIGITS (y), SCM_NUMDIGS (y),
  3339. SCM_BIGSIGN (y) ? (xx > 0) : (xx < 0));
  3340. #else
  3341. SCM_BIGDIG zdigs [SCM_DIGSPERLONG];
  3342. scm_longdigs (xx, zdigs);
  3343. return scm_mulbig (zdigs, SCM_DIGSPERLONG,
  3344. SCM_BDIGITS (y), SCM_NUMDIGS (y),
  3345. SCM_BIGSIGN (y) ? (xx > 0) : (xx < 0));
  3346. #endif
  3347. } else if (SCM_REALP (y)) {
  3348. return scm_make_real (xx * SCM_REAL_VALUE (y));
  3349. } else if (SCM_COMPLEXP (y)) {
  3350. return scm_make_complex (xx * SCM_COMPLEX_REAL (y),
  3351. xx * SCM_COMPLEX_IMAG (y));
  3352. } else {
  3353. SCM_WTA_DISPATCH_2 (g_product, x, y, SCM_ARGn, s_product);
  3354. }
  3355. } else if (SCM_BIGP (x)) {
  3356. if (SCM_INUMP (y)) {
  3357. SCM_SWAP (x, y);
  3358. goto intbig;
  3359. } else if (SCM_BIGP (y)) {
  3360. return scm_mulbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
  3361. SCM_BDIGITS (y), SCM_NUMDIGS (y),
  3362. SCM_BIGSIGN (x) ^ SCM_BIGSIGN (y));
  3363. } else if (SCM_REALP (y)) {
  3364. return scm_make_real (scm_i_big2dbl (x) * SCM_REAL_VALUE (y));
  3365. } else if (SCM_COMPLEXP (y)) {
  3366. double z = scm_i_big2dbl (x);
  3367. return scm_make_complex (z * SCM_COMPLEX_REAL (y),
  3368. z * SCM_COMPLEX_IMAG (y));
  3369. } else {
  3370. SCM_WTA_DISPATCH_2 (g_product, x, y, SCM_ARGn, s_product);
  3371. }
  3372. } else if (SCM_REALP (x)) {
  3373. if (SCM_INUMP (y)) {
  3374. /* inexact*exact0 => exact 0, per R5RS "Exactness" section */
  3375. if (SCM_EQ_P (y, SCM_INUM0))
  3376. return y;
  3377. return scm_make_real (SCM_INUM (y) * SCM_REAL_VALUE (x));
  3378. } else if (SCM_BIGP (y)) {
  3379. return scm_make_real (scm_i_big2dbl (y) * SCM_REAL_VALUE (x));
  3380. } else if (SCM_REALP (y)) {
  3381. return scm_make_real (SCM_REAL_VALUE (x) * SCM_REAL_VALUE (y));
  3382. } else if (SCM_COMPLEXP (y)) {
  3383. return scm_make_complex (SCM_REAL_VALUE (x) * SCM_COMPLEX_REAL (y),
  3384. SCM_REAL_VALUE (x) * SCM_COMPLEX_IMAG (y));
  3385. } else {
  3386. SCM_WTA_DISPATCH_2 (g_product, x, y, SCM_ARGn, s_product);
  3387. }
  3388. } else if (SCM_COMPLEXP (x)) {
  3389. if (SCM_INUMP (y)) {
  3390. /* inexact*exact0 => exact 0, per R5RS "Exactness" section */
  3391. if (SCM_EQ_P (y, SCM_INUM0))
  3392. return y;
  3393. return scm_make_complex (SCM_INUM (y) * SCM_COMPLEX_REAL (x),
  3394. SCM_INUM (y) * SCM_COMPLEX_IMAG (x));
  3395. } else if (SCM_BIGP (y)) {
  3396. double z = scm_i_big2dbl (y);
  3397. return scm_make_complex (z * SCM_COMPLEX_REAL (x),
  3398. z * SCM_COMPLEX_IMAG (x));
  3399. } else if (SCM_REALP (y)) {
  3400. return scm_make_complex (SCM_REAL_VALUE (y) * SCM_COMPLEX_REAL (x),
  3401. SCM_REAL_VALUE (y) * SCM_COMPLEX_IMAG (x));
  3402. } else if (SCM_COMPLEXP (y)) {
  3403. return scm_make_complex (SCM_COMPLEX_REAL (x) * SCM_COMPLEX_REAL (y)
  3404. - SCM_COMPLEX_IMAG (x) * SCM_COMPLEX_IMAG (y),
  3405. SCM_COMPLEX_REAL (x) * SCM_COMPLEX_IMAG (y)
  3406. + SCM_COMPLEX_IMAG (x) * SCM_COMPLEX_REAL (y));
  3407. } else {
  3408. SCM_WTA_DISPATCH_2 (g_product, x, y, SCM_ARGn, s_product);
  3409. }
  3410. } else {
  3411. SCM_WTA_DISPATCH_2 (g_product, x, y, SCM_ARG1, s_product);
  3412. }
  3413. }
  3414. double
  3415. scm_num2dbl (SCM a, const char *why)
  3416. #define FUNC_NAME why
  3417. {
  3418. if (SCM_INUMP (a)) {
  3419. return (double) SCM_INUM (a);
  3420. } else if (SCM_BIGP (a)) {
  3421. return scm_i_big2dbl (a);
  3422. } else if (SCM_REALP (a)) {
  3423. return (SCM_REAL_VALUE (a));
  3424. } else {
  3425. SCM_WRONG_TYPE_ARG (SCM_ARGn, a);
  3426. }
  3427. }
  3428. #undef FUNC_NAME
  3429. /* The code below for complex division is adapted from the GNU
  3430. libstdc++, which adapted it from f2c's libF77, and is subject to
  3431. this copyright: */
  3432. /****************************************************************
  3433. Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories and Bellcore.
  3434. Permission to use, copy, modify, and distribute this software
  3435. and its documentation for any purpose and without fee is hereby
  3436. granted, provided that the above copyright notice appear in all
  3437. copies and that both that the copyright notice and this
  3438. permission notice and warranty disclaimer appear in supporting
  3439. documentation, and that the names of AT&T Bell Laboratories or
  3440. Bellcore or any of their entities not be used in advertising or
  3441. publicity pertaining to distribution of the software without
  3442. specific, written prior permission.
  3443. AT&T and Bellcore disclaim all warranties with regard to this
  3444. software, including all implied warranties of merchantability
  3445. and fitness. In no event shall AT&T or Bellcore be liable for
  3446. any special, indirect or consequential damages or any damages
  3447. whatsoever resulting from loss of use, data or profits, whether
  3448. in an action of contract, negligence or other tortious action,
  3449. arising out of or in connection with the use or performance of
  3450. this software.
  3451. ****************************************************************/
  3452. SCM_GPROC1 (s_divide, "/", scm_tc7_asubr, scm_divide, g_divide);
  3453. /* Divide the first argument by the product of the remaining
  3454. arguments. If called with one argument @var{z1}, 1/@var{z1} is
  3455. returned. */
  3456. #define FUNC_NAME s_divide
  3457. SCM
  3458. scm_divide (SCM x, SCM y)
  3459. {
  3460. double a;
  3461. if (SCM_UNBNDP (y)) {
  3462. if (SCM_UNBNDP (x)) {
  3463. SCM_WTA_DISPATCH_0 (g_divide, s_divide);
  3464. } else if (SCM_INUMP (x)) {
  3465. if (SCM_EQ_P (x, SCM_MAKINUM (1L)) || SCM_EQ_P (x, SCM_MAKINUM (-1L))) {
  3466. return x;
  3467. } else {
  3468. return scm_make_real (1.0 / (double) SCM_INUM (x));
  3469. }
  3470. } else if (SCM_BIGP (x)) {
  3471. return scm_make_real (1.0 / scm_i_big2dbl (x));
  3472. } else if (SCM_REALP (x)) {
  3473. return scm_make_real (1.0 / SCM_REAL_VALUE (x));
  3474. } else if (SCM_COMPLEXP (x)) {
  3475. double r = SCM_COMPLEX_REAL (x);
  3476. double i = SCM_COMPLEX_IMAG (x);
  3477. if (fabs(r) <= fabs(i)) {
  3478. double t = r / i;
  3479. double d = i * (1.0 + t * t);
  3480. return scm_make_complex (t / d, -1.0 / d);
  3481. } else {
  3482. double t = i / r;
  3483. double d = r * (1.0 + t * t);
  3484. return scm_make_complex (1.0 / d, -t / d);
  3485. }
  3486. } else {
  3487. SCM_WTA_DISPATCH_1 (g_divide, x, SCM_ARG1, s_divide);
  3488. }
  3489. }
  3490. if (SCM_INUMP (x)) {
  3491. long xx = SCM_INUM (x);
  3492. if (SCM_INUMP (y)) {
  3493. long yy = SCM_INUM (y);
  3494. if (yy == 0) {
  3495. scm_num_overflow (s_divide);
  3496. } else if (xx % yy != 0) {
  3497. return scm_make_real ((double) xx / (double) yy);
  3498. } else {
  3499. long z = xx / yy;
  3500. if (SCM_FIXABLE (z)) {
  3501. return SCM_MAKINUM (z);
  3502. } else {
  3503. #ifdef SCM_BIGDIG
  3504. return scm_i_long2big (z);
  3505. #else
  3506. return scm_make_real ((double) xx / (double) yy);
  3507. #endif
  3508. }
  3509. }
  3510. } else if (SCM_BIGP (y)) {
  3511. return scm_make_real ((double) xx / scm_i_big2dbl (y));
  3512. } else if (SCM_REALP (y)) {
  3513. return scm_make_real ((double) xx / SCM_REAL_VALUE (y));
  3514. } else if (SCM_COMPLEXP (y)) {
  3515. a = xx;
  3516. complex_div: /* y _must_ be a complex number */
  3517. {
  3518. double r = SCM_COMPLEX_REAL (y);
  3519. double i = SCM_COMPLEX_IMAG (y);
  3520. if (fabs(r) <= fabs(i)) {
  3521. double t = r / i;
  3522. double d = i * (1.0 + t * t);
  3523. return scm_make_complex ((a * t) / d, -a / d);
  3524. } else {
  3525. double t = i / r;
  3526. double d = r * (1.0 + t * t);
  3527. return scm_make_complex (a / d, -(a * t) / d);
  3528. }
  3529. }
  3530. } else {
  3531. SCM_WTA_DISPATCH_2 (g_divide, x, y, SCM_ARGn, s_divide);
  3532. }
  3533. } else if (SCM_BIGP (x)) {
  3534. if (SCM_INUMP (y)) {
  3535. long int yy = SCM_INUM (y);
  3536. if (yy == 0) {
  3537. scm_num_overflow (s_divide);
  3538. } else if (yy == 1) {
  3539. return x;
  3540. } else {
  3541. long z = yy < 0 ? -yy : yy;
  3542. if (z < SCM_BIGRAD) {
  3543. SCM w = scm_i_copybig (x, SCM_BIGSIGN (x) ? (yy > 0) : (yy < 0));
  3544. return scm_divbigdig (SCM_BDIGITS (w), SCM_NUMDIGS (w),
  3545. (SCM_BIGDIG) z)
  3546. ? scm_make_real (scm_i_big2dbl (x) / (double) yy)
  3547. : scm_i_normbig (w);
  3548. } else {
  3549. SCM w;
  3550. #ifndef SCM_DIGSTOOBIG
  3551. z = scm_pseudolong (z);
  3552. w = scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
  3553. (SCM_BIGDIG *) & z, SCM_DIGSPERLONG,
  3554. SCM_BIGSIGN (x) ? (yy > 0) : (yy < 0), 3);
  3555. #else
  3556. SCM_BIGDIG zdigs[SCM_DIGSPERLONG];
  3557. scm_longdigs (z, zdigs);
  3558. w = scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
  3559. zdigs, SCM_DIGSPERLONG,
  3560. SCM_BIGSIGN (x) ? (yy > 0) : (yy < 0), 3);
  3561. #endif
  3562. return (!SCM_UNBNDP (w))
  3563. ? w
  3564. : scm_make_real (scm_i_big2dbl (x) / (double) yy);
  3565. }
  3566. }
  3567. } else if (SCM_BIGP (y)) {
  3568. SCM w = scm_divbigbig (SCM_BDIGITS (x), SCM_NUMDIGS (x),
  3569. SCM_BDIGITS (y), SCM_NUMDIGS (y),
  3570. SCM_BIGSIGN (x) ^ SCM_BIGSIGN (y), 3);
  3571. return (!SCM_UNBNDP (w))
  3572. ? w
  3573. : scm_make_real (scm_i_big2dbl (x) / scm_i_big2dbl (y));
  3574. } else if (SCM_REALP (y)) {
  3575. return scm_make_real (scm_i_big2dbl (x) / SCM_REAL_VALUE (y));
  3576. } else if (SCM_COMPLEXP (y)) {
  3577. a = scm_i_big2dbl (x);
  3578. goto complex_div;
  3579. } else {
  3580. SCM_WTA_DISPATCH_2 (g_divide, x, y, SCM_ARGn, s_divide);
  3581. }
  3582. } else if (SCM_REALP (x)) {
  3583. double rx = SCM_REAL_VALUE (x);
  3584. if (SCM_INUMP (y)) {
  3585. return scm_make_real (rx / (double) SCM_INUM (y));
  3586. } else if (SCM_BIGP (y)) {
  3587. return scm_make_real (rx / scm_i_big2dbl (y));
  3588. } else if (SCM_REALP (y)) {
  3589. return scm_make_real (rx / SCM_REAL_VALUE (y));
  3590. } else if (SCM_COMPLEXP (y)) {
  3591. a = rx;
  3592. goto complex_div;
  3593. } else {
  3594. SCM_WTA_DISPATCH_2 (g_divide, x, y, SCM_ARGn, s_divide);
  3595. }
  3596. } else if (SCM_COMPLEXP (x)) {
  3597. double rx = SCM_COMPLEX_REAL (x);
  3598. double ix = SCM_COMPLEX_IMAG (x);
  3599. if (SCM_INUMP (y)) {
  3600. double d = SCM_INUM (y);
  3601. return scm_make_complex (rx / d, ix / d);
  3602. } else if (SCM_BIGP (y)) {
  3603. double d = scm_i_big2dbl (y);
  3604. return scm_make_complex (rx / d, ix / d);
  3605. } else if (SCM_REALP (y)) {
  3606. double d = SCM_REAL_VALUE (y);
  3607. return scm_make_complex (rx / d, ix / d);
  3608. } else if (SCM_COMPLEXP (y)) {
  3609. double ry = SCM_COMPLEX_REAL (y);
  3610. double iy = SCM_COMPLEX_IMAG (y);
  3611. if (fabs(ry) <= fabs(iy)) {
  3612. double t = ry / iy;
  3613. double d = iy * (1.0 + t * t);
  3614. return scm_make_complex ((rx * t + ix) / d, (ix * t - rx) / d);
  3615. } else {
  3616. double t = iy / ry;
  3617. double d = ry * (1.0 + t * t);
  3618. return scm_make_complex ((rx + ix * t) / d, (ix - rx * t) / d);
  3619. }
  3620. } else {
  3621. SCM_WTA_DISPATCH_2 (g_divide, x, y, SCM_ARGn, s_divide);
  3622. }
  3623. } else {
  3624. SCM_WTA_DISPATCH_2 (g_divide, x, y, SCM_ARG1, s_divide);
  3625. }
  3626. }
  3627. #undef FUNC_NAME
  3628. SCM_GPROC1 (s_asinh, "$asinh", scm_tc7_cxr, (SCM (*)()) scm_asinh, g_asinh);
  3629. /* "Return the inverse hyperbolic sine of @var{x}."
  3630. */
  3631. double
  3632. scm_asinh (double x)
  3633. {
  3634. return log (x + sqrt (x * x + 1));
  3635. }
  3636. SCM_GPROC1 (s_acosh, "$acosh", scm_tc7_cxr, (SCM (*)()) scm_acosh, g_acosh);
  3637. /* "Return the inverse hyperbolic cosine of @var{x}."
  3638. */
  3639. double
  3640. scm_acosh (double x)
  3641. {
  3642. return log (x + sqrt (x * x - 1));
  3643. }
  3644. SCM_GPROC1 (s_atanh, "$atanh", scm_tc7_cxr, (SCM (*)()) scm_atanh, g_atanh);
  3645. /* "Return the inverse hyperbolic tangent of @var{x}."
  3646. */
  3647. double
  3648. scm_atanh (double x)
  3649. {
  3650. return 0.5 * log ((1 + x) / (1 - x));
  3651. }
  3652. SCM_PRIMITIVE_GENERIC (scm_truncate_number, "truncate", 1, 0, 0,
  3653. (SCM x),
  3654. "Round the inexact number @var{x} towards zero.")
  3655. #define FUNC_NAME s_scm_truncate_number
  3656. {
  3657. if (SCM_INUMP (x) || SCM_BIGP (x))
  3658. return x;
  3659. else if (SCM_REALP (x))
  3660. return scm_make_real (scm_truncate (SCM_REAL_VALUE (x)));
  3661. else
  3662. SCM_WTA_DISPATCH_1 (g_scm_truncate_number, x, 1, s_scm_truncate_number);
  3663. }
  3664. #undef FUNC_NAME
  3665. double
  3666. scm_truncate (double x)
  3667. {
  3668. if (x < 0.0)
  3669. return -floor (-x);
  3670. return floor (x);
  3671. }
  3672. /* scm_round is done using floor(x+0.5) to round to nearest and with
  3673. half-way case (ie. when x is an integer plus 0.5) going upwards. Then
  3674. half-way cases are identified and adjusted down if the round-upwards
  3675. didn't give the desired even integer.
  3676. "plus_half == result" identifies a half-way case. If plus_half, which is
  3677. x + 0.5, is an integer then x must be an integer plus 0.5.
  3678. An odd "result" value is identified with result/2 != floor(result/2).
  3679. This is done with plus_half, since that value is ready for use sooner in
  3680. a pipelined cpu, and we're already requiring plus_half == result.
  3681. Note however that we need to be careful when x is big and already an
  3682. integer. In that case "x+0.5" may round to an adjacent integer, causing
  3683. us to return such a value, incorrectly. For instance if the hardware is
  3684. in the usual default nearest-even rounding, then for x = 0x1FFFFFFFFFFFFF
  3685. (ie. 53 one bits) we will have x+0.5 = 0x20000000000000 and that value
  3686. returned. Or if the hardware is in round-upwards mode, then other bigger
  3687. values like say x == 2^128 will see x+0.5 rounding up to the next higher
  3688. representable value, 2^128+2^76 (or whatever), again incorrect.
  3689. These bad roundings of x+0.5 are avoided by testing at the start whether
  3690. x is already an integer. If it is then clearly that's the desired result
  3691. already. And if it's not then the exponent must be small enough to allow
  3692. an 0.5 to be represented, and hence added without a bad rounding. */
  3693. double
  3694. scm_round (double x)
  3695. {
  3696. double plus_half, result;
  3697. if (x == floor (x))
  3698. return x;
  3699. plus_half = x + 0.5;
  3700. result = floor (plus_half);
  3701. /* Adjust so that the scm_round is towards even. */
  3702. return (plus_half == result && plus_half / 2 != floor (plus_half / 2))
  3703. ? result - 1 : result;
  3704. }
  3705. SCM_PRIMITIVE_GENERIC (scm_round_number, "round", 1, 0, 0,
  3706. (SCM x),
  3707. "Round the number @var{x} towards the nearest integer. "
  3708. "When it is exactly halfway between two integers, "
  3709. "round towards the even one.")
  3710. #define FUNC_NAME s_scm_round_number
  3711. {
  3712. if (SCM_INUMP (x) || SCM_BIGP (x))
  3713. return x;
  3714. else if (SCM_REALP (x))
  3715. return scm_make_real (scm_round (SCM_REAL_VALUE (x)));
  3716. else
  3717. SCM_WTA_DISPATCH_1 (g_scm_round_number, x, 1, s_scm_round_number);
  3718. }
  3719. #undef FUNC_NAME
  3720. SCM_GPROC1 (s_exact_to_inexact, "exact->inexact", scm_tc7_cxr, (SCM (*)()) scm_exact_to_inexact, g_exact_to_inexact);
  3721. /* Convert the number @var{x} to its inexact representation.\n"
  3722. */
  3723. double
  3724. scm_exact_to_inexact (double z)
  3725. {
  3726. return z;
  3727. }
  3728. SCM_PRIMITIVE_GENERIC (scm_floor, "floor", 1, 0, 0,
  3729. (SCM x),
  3730. "Round the number @var{x} towards minus infinity.")
  3731. #define FUNC_NAME s_scm_floor
  3732. {
  3733. if (SCM_INUMP (x) || SCM_BIGP (x))
  3734. return x;
  3735. else if (SCM_REALP (x))
  3736. return scm_make_real (floor (SCM_REAL_VALUE (x)));
  3737. else
  3738. SCM_WTA_DISPATCH_1 (g_scm_floor, x, 1, s_scm_floor);
  3739. }
  3740. #undef FUNC_NAME
  3741. SCM_PRIMITIVE_GENERIC (scm_ceiling, "ceiling", 1, 0, 0,
  3742. (SCM x),
  3743. "Round the number @var{x} towards infinity.")
  3744. #define FUNC_NAME s_scm_ceiling
  3745. {
  3746. if (SCM_INUMP (x) || SCM_BIGP (x))
  3747. return x;
  3748. else if (SCM_REALP (x))
  3749. return scm_make_real (ceil (SCM_REAL_VALUE (x)));
  3750. else
  3751. SCM_WTA_DISPATCH_1 (g_scm_ceiling, x, 1, s_scm_ceiling);
  3752. }
  3753. #undef FUNC_NAME
  3754. SCM_GPROC1 (s_i_sqrt, "$sqrt", scm_tc7_cxr, (SCM (*)()) sqrt, g_i_sqrt);
  3755. /* "Return the square root of the real number @var{x}."
  3756. */
  3757. SCM_GPROC1 (s_i_abs, "$abs", scm_tc7_cxr, (SCM (*)()) fabs, g_i_abs);
  3758. /* "Return the absolute value of the real number @var{x}."
  3759. */
  3760. SCM_GPROC1 (s_i_exp, "$exp", scm_tc7_cxr, (SCM (*)()) exp, g_i_exp);
  3761. /* "Return the @var{x}th power of e."
  3762. */
  3763. SCM_GPROC1 (s_i_log, "$log", scm_tc7_cxr, (SCM (*)()) log, g_i_log);
  3764. /* "Return the natural logarithm of the real number @var{x}."
  3765. */
  3766. SCM_GPROC1 (s_i_sin, "$sin", scm_tc7_cxr, (SCM (*)()) sin, g_i_sin);
  3767. /* "Return the sine of the real number @var{x}."
  3768. */
  3769. SCM_GPROC1 (s_i_cos, "$cos", scm_tc7_cxr, (SCM (*)()) cos, g_i_cos);
  3770. /* "Return the cosine of the real number @var{x}."
  3771. */
  3772. SCM_GPROC1 (s_i_tan, "$tan", scm_tc7_cxr, (SCM (*)()) tan, g_i_tan);
  3773. /* "Return the tangent of the real number @var{x}."
  3774. */
  3775. SCM_GPROC1 (s_i_asin, "$asin", scm_tc7_cxr, (SCM (*)()) asin, g_i_asin);
  3776. /* "Return the arc sine of the real number @var{x}."
  3777. */
  3778. SCM_GPROC1 (s_i_acos, "$acos", scm_tc7_cxr, (SCM (*)()) acos, g_i_acos);
  3779. /* "Return the arc cosine of the real number @var{x}."
  3780. */
  3781. SCM_GPROC1 (s_i_atan, "$atan", scm_tc7_cxr, (SCM (*)()) atan, g_i_atan);
  3782. /* "Return the arc tangent of the real number @var{x}."
  3783. */
  3784. SCM_GPROC1 (s_i_sinh, "$sinh", scm_tc7_cxr, (SCM (*)()) sinh, g_i_sinh);
  3785. /* "Return the hyperbolic sine of the real number @var{x}."
  3786. */
  3787. SCM_GPROC1 (s_i_cosh, "$cosh", scm_tc7_cxr, (SCM (*)()) cosh, g_i_cosh);
  3788. /* "Return the hyperbolic cosine of the real number @var{x}."
  3789. */
  3790. SCM_GPROC1 (s_i_tanh, "$tanh", scm_tc7_cxr, (SCM (*)()) tanh, g_i_tanh);
  3791. /* "Return the hyperbolic tangent of the real number @var{x}."
  3792. */
  3793. struct dpair
  3794. {
  3795. double x, y;
  3796. };
  3797. static void scm_two_doubles (SCM x,
  3798. SCM y,
  3799. const char *sstring,
  3800. struct dpair * xy);
  3801. static void
  3802. scm_two_doubles (SCM x, SCM y, const char *sstring, struct dpair *xy)
  3803. {
  3804. if (SCM_INUMP (x)) {
  3805. xy->x = SCM_INUM (x);
  3806. } else if (SCM_BIGP (x)) {
  3807. xy->x = scm_i_big2dbl (x);
  3808. } else if (SCM_REALP (x)) {
  3809. xy->x = SCM_REAL_VALUE (x);
  3810. } else {
  3811. scm_wrong_type_arg (sstring, SCM_ARG1, x);
  3812. }
  3813. if (SCM_INUMP (y)) {
  3814. xy->y = SCM_INUM (y);
  3815. } else if (SCM_BIGP (y)) {
  3816. xy->y = scm_i_big2dbl (y);
  3817. } else if (SCM_REALP (y)) {
  3818. xy->y = SCM_REAL_VALUE (y);
  3819. } else {
  3820. scm_wrong_type_arg (sstring, SCM_ARG2, y);
  3821. }
  3822. }
  3823. SCM_DEFINE (scm_sys_expt, "$expt", 2, 0, 0,
  3824. (SCM x, SCM y),
  3825. "Return @var{x} raised to the power of @var{y}. This\n"
  3826. "procedure does not accept complex arguments.")
  3827. #define FUNC_NAME s_scm_sys_expt
  3828. {
  3829. struct dpair xy;
  3830. scm_two_doubles (x, y, FUNC_NAME, &xy);
  3831. return scm_make_real (pow (xy.x, xy.y));
  3832. }
  3833. #undef FUNC_NAME
  3834. SCM_DEFINE (scm_sys_atan2, "$atan2", 2, 0, 0,
  3835. (SCM x, SCM y),
  3836. "Return the arc tangent of the two arguments @var{x} and\n"
  3837. "@var{y}. This is similar to calculating the arc tangent of\n"
  3838. "@var{x} / @var{y}, except that the signs of both arguments\n"
  3839. "are used to determine the quadrant of the result. This\n"
  3840. "procedure does not accept complex arguments.")
  3841. #define FUNC_NAME s_scm_sys_atan2
  3842. {
  3843. struct dpair xy;
  3844. scm_two_doubles (x, y, FUNC_NAME, &xy);
  3845. return scm_make_real (atan2 (xy.x, xy.y));
  3846. }
  3847. #undef FUNC_NAME
  3848. SCM_DEFINE (scm_make_rectangular, "make-rectangular", 2, 0, 0,
  3849. (SCM real, SCM imaginary),
  3850. "Return a complex number constructed of the given @var{real} and\n"
  3851. "@var{imaginary} parts.")
  3852. #define FUNC_NAME s_scm_make_rectangular
  3853. {
  3854. struct dpair xy;
  3855. scm_two_doubles (real, imaginary, FUNC_NAME, &xy);
  3856. return scm_make_complex (xy.x, xy.y);
  3857. }
  3858. #undef FUNC_NAME
  3859. SCM_DEFINE (scm_make_polar, "make-polar", 2, 0, 0,
  3860. (SCM x, SCM y),
  3861. "Return the complex number @var{x} * e^(i * @var{y}).")
  3862. #define FUNC_NAME s_scm_make_polar
  3863. {
  3864. struct dpair xy;
  3865. scm_two_doubles (x, y, FUNC_NAME, &xy);
  3866. return scm_make_complex (xy.x * cos (xy.y), xy.x * sin (xy.y));
  3867. }
  3868. #undef FUNC_NAME
  3869. SCM_GPROC (s_real_part, "real-part", 1, 0, 0, scm_real_part, g_real_part);
  3870. /* "Return the real part of the number @var{z}."
  3871. */
  3872. SCM
  3873. scm_real_part (SCM z)
  3874. {
  3875. if (SCM_INUMP (z)) {
  3876. return z;
  3877. } else if (SCM_BIGP (z)) {
  3878. return z;
  3879. } else if (SCM_REALP (z)) {
  3880. return z;
  3881. } else if (SCM_COMPLEXP (z)) {
  3882. return scm_make_real (SCM_COMPLEX_REAL (z));
  3883. } else {
  3884. SCM_WTA_DISPATCH_1 (g_real_part, z, SCM_ARG1, s_real_part);
  3885. }
  3886. }
  3887. SCM_GPROC (s_imag_part, "imag-part", 1, 0, 0, scm_imag_part, g_imag_part);
  3888. /* "Return the imaginary part of the number @var{z}."
  3889. */
  3890. SCM
  3891. scm_imag_part (SCM z)
  3892. {
  3893. if (SCM_INUMP (z)) {
  3894. return SCM_INUM0;
  3895. } else if (SCM_BIGP (z)) {
  3896. return SCM_INUM0;
  3897. } else if (SCM_REALP (z)) {
  3898. return scm_flo0;
  3899. } else if (SCM_COMPLEXP (z)) {
  3900. return scm_make_real (SCM_COMPLEX_IMAG (z));
  3901. } else {
  3902. SCM_WTA_DISPATCH_1 (g_imag_part, z, SCM_ARG1, s_imag_part);
  3903. }
  3904. }
  3905. SCM_GPROC (s_magnitude, "magnitude", 1, 0, 0, scm_magnitude, g_magnitude);
  3906. /* "Return the magnitude of the number @var{z}. This is the same as\n"
  3907. * "@code{abs} for real arguments, but also allows complex numbers."
  3908. */
  3909. SCM
  3910. scm_magnitude (SCM z)
  3911. {
  3912. if (SCM_INUMP (z)) {
  3913. long int zz = SCM_INUM (z);
  3914. if (zz >= 0) {
  3915. return z;
  3916. } else if (SCM_POSFIXABLE (-zz)) {
  3917. return SCM_MAKINUM (-zz);
  3918. } else {
  3919. #ifdef SCM_BIGDIG
  3920. return scm_i_long2big (-zz);
  3921. #else
  3922. scm_num_overflow (s_magnitude);
  3923. #endif
  3924. }
  3925. } else if (SCM_BIGP (z)) {
  3926. if (!SCM_BIGSIGN (z)) {
  3927. return z;
  3928. } else {
  3929. return scm_i_copybig (z, 0);
  3930. }
  3931. } else if (SCM_REALP (z)) {
  3932. return scm_make_real (fabs (SCM_REAL_VALUE (z)));
  3933. } else if (SCM_COMPLEXP (z)) {
  3934. double r = SCM_COMPLEX_REAL (z);
  3935. double i = SCM_COMPLEX_IMAG (z);
  3936. return scm_make_real (sqrt (i * i + r * r));
  3937. } else {
  3938. SCM_WTA_DISPATCH_1 (g_magnitude, z, SCM_ARG1, s_magnitude);
  3939. }
  3940. }
  3941. SCM_GPROC (s_angle, "angle", 1, 0, 0, scm_angle, g_angle);
  3942. /* "Return the angle of the complex number @var{z}."
  3943. */
  3944. SCM
  3945. scm_angle (SCM z)
  3946. {
  3947. if (SCM_INUMP (z)) {
  3948. if (SCM_INUM (z) >= 0) {
  3949. return scm_make_real (atan2 (0.0, 1.0));
  3950. } else {
  3951. return scm_make_real (atan2 (0.0, -1.0));
  3952. }
  3953. } else if (SCM_BIGP (z)) {
  3954. if (SCM_BIGSIGN (z)) {
  3955. return scm_make_real (atan2 (0.0, -1.0));
  3956. } else {
  3957. return scm_make_real (atan2 (0.0, 1.0));
  3958. }
  3959. } else if (SCM_REALP (z)) {
  3960. return scm_make_real (atan2 (0.0, SCM_REAL_VALUE (z)));
  3961. } else if (SCM_COMPLEXP (z)) {
  3962. return scm_make_real (atan2 (SCM_COMPLEX_IMAG (z), SCM_COMPLEX_REAL (z)));
  3963. } else {
  3964. SCM_WTA_DISPATCH_1 (g_angle, z, SCM_ARG1, s_angle);
  3965. }
  3966. }
  3967. SCM_DEFINE (scm_inexact_to_exact, "inexact->exact", 1, 0, 0,
  3968. (SCM z),
  3969. "Return an exact number that is numerically closest to @var{z}.")
  3970. #define FUNC_NAME s_scm_inexact_to_exact
  3971. {
  3972. if (SCM_INUMP (z)) {
  3973. return z;
  3974. } else if (SCM_BIGP (z)) {
  3975. return z;
  3976. } else if (SCM_REALP (z)) {
  3977. double u = floor (SCM_REAL_VALUE (z) + 0.5);
  3978. long lu = (long) u;
  3979. if (SCM_FIXABLE (lu)) {
  3980. return SCM_MAKINUM (lu);
  3981. #ifdef SCM_BIGDIG
  3982. } else if (isfinite (u)) {
  3983. return scm_i_dbl2big (u);
  3984. #endif
  3985. } else {
  3986. scm_num_overflow (s_scm_inexact_to_exact);
  3987. }
  3988. } else {
  3989. SCM_WRONG_TYPE_ARG (1, z);
  3990. }
  3991. }
  3992. #undef FUNC_NAME
  3993. #ifdef SCM_BIGDIG
  3994. /* d must be integer */
  3995. SCM
  3996. scm_i_dbl2big (double d)
  3997. {
  3998. size_t i = 0;
  3999. long c;
  4000. SCM_BIGDIG *digits;
  4001. SCM ans;
  4002. double u = (d < 0) ? -d : d;
  4003. while (0 != floor (u))
  4004. {
  4005. u /= SCM_BIGRAD;
  4006. i++;
  4007. }
  4008. ans = scm_i_mkbig (i, d < 0);
  4009. digits = SCM_BDIGITS (ans);
  4010. while (i--)
  4011. {
  4012. u *= SCM_BIGRAD;
  4013. c = floor (u);
  4014. u -= c;
  4015. digits[i] = c;
  4016. }
  4017. #ifndef SCM_RECKLESS
  4018. if (u != 0)
  4019. scm_num_overflow ("dbl2big");
  4020. #endif
  4021. return ans;
  4022. }
  4023. double
  4024. scm_i_big2dbl (SCM b)
  4025. {
  4026. double ans = 0.0;
  4027. size_t i = SCM_NUMDIGS (b);
  4028. SCM_BIGDIG *digits = SCM_BDIGITS (b);
  4029. while (i--)
  4030. ans = digits[i] + SCM_BIGRAD * ans;
  4031. if (SCM_BIGSIGN (b))
  4032. return - ans;
  4033. return ans;
  4034. }
  4035. #endif
  4036. #ifdef HAVE_LONG_LONGS
  4037. # ifndef LLONG_MAX
  4038. # define ULLONG_MAX ((unsigned long long) (-1))
  4039. # define LLONG_MAX ((long long) (ULLONG_MAX >> 1))
  4040. # define LLONG_MIN (~LLONG_MAX)
  4041. # endif
  4042. #endif
  4043. #ifndef SIZE_MAX
  4044. #define SIZE_MAX ((size_t) (-1))
  4045. #endif
  4046. #ifndef PTRDIFF_MIN
  4047. /* the below is not really guaranteed to work (I think), but probably does: */
  4048. #define PTRDIFF_MIN ((ptrdiff_t) ((ptrdiff_t)1 << (sizeof (ptrdiff_t)*8 - 1)))
  4049. #endif
  4050. #ifndef PTRDIFF_MAX
  4051. #define PTRDIFF_MAX (~ PTRDIFF_MIN)
  4052. #endif
  4053. #define NUM2INTEGRAL scm_num2short
  4054. #define INTEGRAL2NUM scm_short2num
  4055. #define INTEGRAL2BIG scm_i_short2big
  4056. #define ITYPE short
  4057. #define MIN_VALUE SHRT_MIN
  4058. #define MAX_VALUE SHRT_MAX
  4059. #include "libguile/num2integral.i.c"
  4060. #define NUM2INTEGRAL scm_num2ushort
  4061. #define INTEGRAL2NUM scm_ushort2num
  4062. #define INTEGRAL2BIG scm_i_ushort2big
  4063. #define UNSIGNED
  4064. #define ITYPE unsigned short
  4065. #define MAX_VALUE USHRT_MAX
  4066. #include "libguile/num2integral.i.c"
  4067. #define NUM2INTEGRAL scm_num2int
  4068. #define INTEGRAL2NUM scm_int2num
  4069. #define INTEGRAL2BIG scm_i_int2big
  4070. #define ITYPE int
  4071. #define MIN_VALUE INT_MIN
  4072. #define MAX_VALUE INT_MAX
  4073. #include "libguile/num2integral.i.c"
  4074. #define NUM2INTEGRAL scm_num2uint
  4075. #define INTEGRAL2NUM scm_uint2num
  4076. #define INTEGRAL2BIG scm_i_uint2big
  4077. #define UNSIGNED
  4078. #define ITYPE unsigned int
  4079. #define MAX_VALUE UINT_MAX
  4080. #include "libguile/num2integral.i.c"
  4081. #define NUM2INTEGRAL scm_num2long
  4082. #define INTEGRAL2NUM scm_long2num
  4083. #define INTEGRAL2BIG scm_i_long2big
  4084. #define ITYPE long
  4085. #define MIN_VALUE LONG_MIN
  4086. #define MAX_VALUE LONG_MAX
  4087. #include "libguile/num2integral.i.c"
  4088. #define NUM2INTEGRAL scm_num2ulong
  4089. #define INTEGRAL2NUM scm_ulong2num
  4090. #define INTEGRAL2BIG scm_i_ulong2big
  4091. #define UNSIGNED
  4092. #define ITYPE unsigned long
  4093. #define MAX_VALUE ULONG_MAX
  4094. #include "libguile/num2integral.i.c"
  4095. #define NUM2INTEGRAL scm_num2ptrdiff
  4096. #define INTEGRAL2NUM scm_ptrdiff2num
  4097. #define INTEGRAL2BIG scm_i_ptrdiff2big
  4098. #define ITYPE ptrdiff_t
  4099. #define MIN_VALUE PTRDIFF_MIN
  4100. #define MAX_VALUE PTRDIFF_MAX
  4101. #include "libguile/num2integral.i.c"
  4102. #define NUM2INTEGRAL scm_num2size
  4103. #define INTEGRAL2NUM scm_size2num
  4104. #define INTEGRAL2BIG scm_i_size2big
  4105. #define UNSIGNED
  4106. #define ITYPE size_t
  4107. #define MAX_VALUE SIZE_MAX
  4108. #include "libguile/num2integral.i.c"
  4109. #ifdef HAVE_LONG_LONGS
  4110. #ifndef ULONG_LONG_MAX
  4111. #define ULONG_LONG_MAX (~0ULL)
  4112. #endif
  4113. #define NUM2INTEGRAL scm_num2long_long
  4114. #define INTEGRAL2NUM scm_long_long2num
  4115. #define INTEGRAL2BIG scm_i_long_long2big
  4116. #define ITYPE long long
  4117. #define MIN_VALUE LLONG_MIN
  4118. #define MAX_VALUE LLONG_MAX
  4119. #include "libguile/num2integral.i.c"
  4120. #define NUM2INTEGRAL scm_num2ulong_long
  4121. #define INTEGRAL2NUM scm_ulong_long2num
  4122. #define INTEGRAL2BIG scm_i_ulong_long2big
  4123. #define UNSIGNED
  4124. #define ITYPE unsigned long long
  4125. #define MAX_VALUE ULLONG_MAX
  4126. #include "libguile/num2integral.i.c"
  4127. #endif /* HAVE_LONG_LONGS */
  4128. #define NUM2FLOAT scm_num2float
  4129. #define FLOAT2NUM scm_float2num
  4130. #define FTYPE float
  4131. #include "libguile/num2float.i.c"
  4132. #define NUM2FLOAT scm_num2double
  4133. #define FLOAT2NUM scm_double2num
  4134. #define FTYPE double
  4135. #include "libguile/num2float.i.c"
  4136. #ifdef GUILE_DEBUG
  4137. #define CHECK(type, v) \
  4138. do { \
  4139. if ((v) != scm_num2##type (scm_##type##2num (v), 1, "check_sanity")) \
  4140. abort (); \
  4141. } while (0);
  4142. static void
  4143. check_sanity ()
  4144. {
  4145. CHECK (short, 0);
  4146. CHECK (ushort, 0U);
  4147. CHECK (int, 0);
  4148. CHECK (uint, 0U);
  4149. CHECK (long, 0L);
  4150. CHECK (ulong, 0UL);
  4151. CHECK (size, 0);
  4152. CHECK (ptrdiff, 0);
  4153. CHECK (short, -1);
  4154. CHECK (int, -1);
  4155. CHECK (long, -1L);
  4156. CHECK (ptrdiff, -1);
  4157. CHECK (short, SHRT_MAX);
  4158. CHECK (short, SHRT_MIN);
  4159. CHECK (ushort, USHRT_MAX);
  4160. CHECK (int, INT_MAX);
  4161. CHECK (int, INT_MIN);
  4162. CHECK (uint, UINT_MAX);
  4163. CHECK (long, LONG_MAX);
  4164. CHECK (long, LONG_MIN);
  4165. CHECK (ulong, ULONG_MAX);
  4166. CHECK (size, SIZE_MAX);
  4167. CHECK (ptrdiff, PTRDIFF_MAX);
  4168. CHECK (ptrdiff, PTRDIFF_MIN);
  4169. #ifdef HAVE_LONG_LONGS
  4170. CHECK (long_long, 0LL);
  4171. CHECK (ulong_long, 0ULL);
  4172. CHECK (long_long, -1LL);
  4173. CHECK (long_long, LLONG_MAX);
  4174. CHECK (long_long, LLONG_MIN);
  4175. CHECK (ulong_long, ULLONG_MAX);
  4176. #endif
  4177. }
  4178. #undef CHECK
  4179. #define CHECK \
  4180. scm_internal_catch (SCM_BOOL_T, check_body, &data, check_handler, &data); \
  4181. if (!SCM_FALSEP (data)) abort();
  4182. static SCM
  4183. check_body (void *data)
  4184. {
  4185. SCM num = *(SCM *) data;
  4186. scm_num2ulong (num, 1, NULL);
  4187. return SCM_UNSPECIFIED;
  4188. }
  4189. static SCM
  4190. check_handler (void *data, SCM tag, SCM throw_args)
  4191. {
  4192. SCM *num = (SCM *) data;
  4193. *num = SCM_BOOL_F;
  4194. return SCM_UNSPECIFIED;
  4195. }
  4196. SCM_DEFINE (scm_sys_check_number_conversions, "%check-number-conversions", 0, 0, 0,
  4197. (),
  4198. "Number conversion sanity checking.")
  4199. #define FUNC_NAME s_scm_sys_check_number_conversions
  4200. {
  4201. SCM data = SCM_MAKINUM (-1);
  4202. CHECK;
  4203. data = scm_int2num (INT_MIN);
  4204. CHECK;
  4205. data = scm_ulong2num (ULONG_MAX);
  4206. data = scm_difference (SCM_INUM0, data);
  4207. CHECK;
  4208. data = scm_ulong2num (ULONG_MAX);
  4209. data = scm_sum (SCM_MAKINUM (1), data); data = scm_difference (SCM_INUM0, data);
  4210. CHECK;
  4211. data = scm_int2num (-10000); data = scm_product (data, data); data = scm_product (data, data);
  4212. CHECK;
  4213. return SCM_UNSPECIFIED;
  4214. }
  4215. #undef FUNC_NAME
  4216. #endif
  4217. void
  4218. scm_init_numbers ()
  4219. {
  4220. abs_most_negative_fixnum = scm_i_long2big (- SCM_MOST_NEGATIVE_FIXNUM);
  4221. scm_permanent_object (abs_most_negative_fixnum);
  4222. /* It may be possible to tune the performance of some algorithms by using
  4223. * the following constants to avoid the creation of bignums. Please, before
  4224. * using these values, remember the two rules of program optimization:
  4225. * 1st Rule: Don't do it. 2nd Rule (experts only): Don't do it yet. */
  4226. scm_c_define ("most-positive-fixnum",
  4227. SCM_MAKINUM (SCM_MOST_POSITIVE_FIXNUM));
  4228. scm_c_define ("most-negative-fixnum",
  4229. SCM_MAKINUM (SCM_MOST_NEGATIVE_FIXNUM));
  4230. scm_add_feature ("complex");
  4231. scm_add_feature ("inexact");
  4232. scm_flo0 = scm_make_real (0.0);
  4233. #ifdef DBL_DIG
  4234. scm_dblprec = (DBL_DIG > 20) ? 20 : DBL_DIG;
  4235. #else
  4236. { /* determine floating point precision */
  4237. double f = 0.1;
  4238. double fsum = 1.0 + f;
  4239. while (fsum != 1.0) {
  4240. if (++scm_dblprec > 20) {
  4241. fsum = 1.0;
  4242. } else {
  4243. f /= 10.0;
  4244. fsum = f + 1.0;
  4245. }
  4246. }
  4247. scm_dblprec = scm_dblprec - 1;
  4248. }
  4249. #endif /* DBL_DIG */
  4250. #ifdef GUILE_DEBUG
  4251. check_sanity ();
  4252. #endif
  4253. #include "libguile/numbers.x"
  4254. }
  4255. #if (SCM_DEBUG_DEPRECATED == 0)
  4256. SCM
  4257. scm_mkbig (size_t len, int sign)
  4258. {
  4259. scm_c_issue_deprecation_warning ("`scm_mkbig' is deprecated. "
  4260. "Use `scm_i_mkbig' instead.");
  4261. return scm_i_mkbig (len, sign);
  4262. }
  4263. SCM
  4264. scm_big2inum (SCM b, size_t l)
  4265. {
  4266. scm_c_issue_deprecation_warning ("`scm_big2inum' is deprecated. "
  4267. "Use `scm_i_big2num' instead.");
  4268. return scm_i_big2inum (b, l);
  4269. }
  4270. SCM
  4271. scm_adjbig (SCM b, size_t nlen)
  4272. {
  4273. scm_c_issue_deprecation_warning ("`scm_adjbig' is deprecated. "
  4274. "Use `scm_i_adjbig' instead.");
  4275. return scm_i_adjbig (b, nlen);
  4276. }
  4277. SCM
  4278. scm_normbig (SCM b)
  4279. {
  4280. scm_c_issue_deprecation_warning ("`scm_normbig' is deprecated. "
  4281. "Use `scm_i_normbig' instead.");
  4282. return scm_i_normbig (b);
  4283. }
  4284. SCM
  4285. scm_copybig (SCM b, int sign)
  4286. {
  4287. scm_c_issue_deprecation_warning ("`scm_copybig' is deprecated. "
  4288. "Use `scm_i_copybig' instead.");
  4289. return scm_i_copybig (b, sign);
  4290. }
  4291. SCM
  4292. scm_2ulong2big (unsigned long *np)
  4293. {
  4294. unsigned long n;
  4295. size_t i;
  4296. SCM_BIGDIG *digits;
  4297. SCM ans;
  4298. ans = scm_i_mkbig (2 * SCM_DIGSPERLONG, 0);
  4299. digits = SCM_BDIGITS (ans);
  4300. n = np[0];
  4301. for (i = 0; i < SCM_DIGSPERLONG; ++i)
  4302. {
  4303. digits[i] = SCM_BIGLO (n);
  4304. n = SCM_BIGDN ((unsigned long) n);
  4305. }
  4306. n = np[1];
  4307. for (i = 0; i < SCM_DIGSPERLONG; ++i)
  4308. {
  4309. digits[i + SCM_DIGSPERLONG] = SCM_BIGLO (n);
  4310. n = SCM_BIGDN ((unsigned long) n);
  4311. }
  4312. return ans;
  4313. }
  4314. SCM
  4315. scm_dbl2big (double d)
  4316. {
  4317. scm_c_issue_deprecation_warning ("`scm_dbl2big' is deprecated. "
  4318. "Use `scm_double2num' instead,"
  4319. "or `scm_i_dbl2big'.");
  4320. return scm_i_dbl2big (d);
  4321. }
  4322. double
  4323. scm_big2dbl (SCM b)
  4324. {
  4325. scm_c_issue_deprecation_warning ("`scm_big2dbl' is deprecated. "
  4326. "Use `scm_num2dbl' instead,"
  4327. "or `scm_i_big2dbl'.");
  4328. return scm_i_big2dbl (b);
  4329. }
  4330. #endif
  4331. /*
  4332. Local Variables:
  4333. c-file-style: "gnu"
  4334. End:
  4335. */