Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge 8.7 |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | mistake |
Files: | files | file ages | folders |
SHA3-256: |
13cda7b91c6a17d50b1c4a60272841d9 |
User & Date: | jan.nijtmans 2019-02-26 20:18:10.205 |
Context
2019-02-26
| ||
20:18 | Merge 8.7 Closed-Leaf check-in: 13cda7b91c user: jan.nijtmans tags: mistake | |
19:37 | More use of (efficient) TclHasIntRep() macro. Also eliminate many (size_t) and (unsigned) type-casts... check-in: 2c7db3fa01 user: jan.nijtmans tags: mistake | |
2019-02-25
| ||
21:15 | Merge 8.7 check-in: 5a8767b61e user: jan.nijtmans tags: trunk | |
Changes
Changes to generic/tclBasic.c.
︙ | ︙ | |||
6817 6818 6819 6820 6821 6822 6823 | } } break; case TCL_NUMBER_BIG: if (Tcl_GetBignumFromObj(interp, objv[1], &big) != TCL_OK) { return TCL_ERROR; } | | | 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 | } } break; case TCL_NUMBER_BIG: if (Tcl_GetBignumFromObj(interp, objv[1], &big) != TCL_OK) { return TCL_ERROR; } if (mp_isneg(&big)) { mp_clear(&big); goto negarg; } break; default: if (TclGetWideIntFromObj(interp, objv[1], &w) != TCL_OK) { return TCL_ERROR; |
︙ | ︙ |
Changes to generic/tclBinary.c.
︙ | ︙ | |||
639 640 641 642 643 644 645 | srcArrayPtr = GET_BYTEARRAY(TclFetchIntRep(srcPtr, &tclByteArrayType)); length = srcArrayPtr->used; copyArrayPtr = ckalloc(BYTEARRAY_SIZE(length)); copyArrayPtr->used = length; copyArrayPtr->allocated = length; | | | | 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 | srcArrayPtr = GET_BYTEARRAY(TclFetchIntRep(srcPtr, &tclByteArrayType)); length = srcArrayPtr->used; copyArrayPtr = ckalloc(BYTEARRAY_SIZE(length)); copyArrayPtr->used = length; copyArrayPtr->allocated = length; memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, length); SET_BYTEARRAY(&ir, copyArrayPtr); Tcl_StoreIntRep(copyPtr, &tclByteArrayType, &ir); } static void DupProperByteArrayInternalRep( Tcl_Obj *srcPtr, /* Object with internal rep to copy. */ Tcl_Obj *copyPtr) /* Object with internal rep to set. */ { unsigned int length; ByteArray *srcArrayPtr, *copyArrayPtr; Tcl_ObjIntRep ir; srcArrayPtr = GET_BYTEARRAY(TclFetchIntRep(srcPtr, &properByteArrayType)); length = srcArrayPtr->used; copyArrayPtr = Tcl_Alloc(BYTEARRAY_SIZE(length)); copyArrayPtr->used = length; copyArrayPtr->allocated = length; memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, length); SET_BYTEARRAY(&ir, copyArrayPtr); Tcl_StoreIntRep(copyPtr, &properByteArrayType, &ir); } /* *---------------------------------------------------------------------- |
︙ | ︙ |
Changes to generic/tclCompile.c.
︙ | ︙ | |||
2985 2986 2987 2988 2989 2990 2991 | localPtr = procPtr->firstLocalPtr; for (i = 0; i < localCt; i++) { if (!TclIsVarTemporary(localPtr)) { char *localName = localPtr->name; if ((nameBytes == localPtr->nameLength) && | | | 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 | localPtr = procPtr->firstLocalPtr; for (i = 0; i < localCt; i++) { if (!TclIsVarTemporary(localPtr)) { char *localName = localPtr->name; if ((nameBytes == localPtr->nameLength) && (strncmp(name, localName, nameBytes) == 0)) { return i; } } localPtr = localPtr->nextPtr; } } |
︙ | ︙ |
Changes to generic/tclFileName.c.
︙ | ︙ | |||
2547 2548 2549 2550 2551 2552 2553 | *--------------------------------------------------------------------------- */ unsigned Tcl_GetFSDeviceFromStat( const Tcl_StatBuf *statPtr) { | | | | | 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 | *--------------------------------------------------------------------------- */ unsigned Tcl_GetFSDeviceFromStat( const Tcl_StatBuf *statPtr) { return statPtr->st_dev; } unsigned Tcl_GetFSInodeFromStat( const Tcl_StatBuf *statPtr) { return statPtr->st_ino; } unsigned Tcl_GetModeFromStat( const Tcl_StatBuf *statPtr) { return statPtr->st_mode; } int Tcl_GetLinkCountFromStat( const Tcl_StatBuf *statPtr) { return (int)statPtr->st_nlink; |
︙ | ︙ | |||
2638 2639 2640 2641 2642 2643 2644 | } unsigned Tcl_GetBlockSizeFromStat( const Tcl_StatBuf *statPtr) { #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE | | | 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 | } unsigned Tcl_GetBlockSizeFromStat( const Tcl_StatBuf *statPtr) { #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE return statPtr->st_blksize; #else /* * Not a great guess, but will do... */ return GUESSED_BLOCK_SIZE; #endif |
︙ | ︙ |
Changes to generic/tclInt.h.
︙ | ︙ | |||
2803 2804 2805 2806 2807 2808 2809 | /* Procedure that unloads a loaded module */ }; /* Flags for conversion of doubles to digit strings */ #define TCL_DD_SHORTEST 0x4 /* Use the shortest possible string */ | < < < < < < | 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 | /* Procedure that unloads a loaded module */ }; /* Flags for conversion of doubles to digit strings */ #define TCL_DD_SHORTEST 0x4 /* Use the shortest possible string */ #define TCL_DD_E_FORMAT 0x2 /* Use a fixed-length string of digits, * suitable for E format*/ #define TCL_DD_F_FORMAT 0x3 /* Use a fixed number of digits after the * decimal point, suitable for F format */ #define TCL_DD_SHORTEN_FLAG 0x4 /* Allow return of a shorter digit string * if it converts losslessly */ #define TCL_DD_NO_QUICK 0x8 /* Debug flag: forbid quick FP conversion */ #define TCL_DD_CONVERSION_TYPE_MASK 0x3 /* Mask to isolate the conversion type */ /* *---------------------------------------------------------------- * Procedures shared among Tcl modules but not used by the outside world: *---------------------------------------------------------------- */ |
︙ | ︙ | |||
4501 4502 4503 4504 4505 4506 4507 | } \ newPtr = (Tcl_Token *) Tcl_Realloc((char *) oldPtr, \ (allocated * sizeof(Tcl_Token))); \ } \ (available) = allocated; \ if (oldPtr == NULL) { \ memcpy(newPtr, staticPtr, \ | | | 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 | } \ newPtr = (Tcl_Token *) Tcl_Realloc((char *) oldPtr, \ (allocated * sizeof(Tcl_Token))); \ } \ (available) = allocated; \ if (oldPtr == NULL) { \ memcpy(newPtr, staticPtr, \ used * sizeof(Tcl_Token)); \ } \ (tokenPtr) = newPtr; \ } \ } while (0) #define TclGrowParseTokenArray(parsePtr, append) \ TclGrowTokenArray((parsePtr)->tokenPtr, (parsePtr)->numTokens, \ |
︙ | ︙ |
Changes to generic/tclInterp.c.
︙ | ︙ | |||
1827 1828 1829 1830 1831 1832 1833 | listPtr = Tcl_NewListObj(cmdc, NULL); listRep = ListRepPtr(listPtr); listRep->elemCount = cmdc; cmdv = &listRep->elements; prefv = &aliasPtr->objPtr; | | | | 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 | listPtr = Tcl_NewListObj(cmdc, NULL); listRep = ListRepPtr(listPtr); listRep->elemCount = cmdc; cmdv = &listRep->elements; prefv = &aliasPtr->objPtr; memcpy(cmdv, prefv, prefc * sizeof(Tcl_Obj *)); memcpy(cmdv+prefc, objv+1, (objc-1) * sizeof(Tcl_Obj *)); for (i=0; i<cmdc; i++) { Tcl_IncrRefCount(cmdv[i]); } /* * Use the ensemble rewriting machinery to ensure correct error messages: |
︙ | ︙ |
Changes to generic/tclObj.c.
︙ | ︙ | |||
2707 2708 2709 2710 2711 2712 2713 | * Must check for those bignum values that can fit in a long, even * when auto-narrowing is enabled. Only those values in the signed * long range get auto-narrowed to tclIntType, while all the * values in the unsigned long range will fit in a long. */ mp_int big; | < < < < | | > | | | | | | | | | | | | < | 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 | * Must check for those bignum values that can fit in a long, even * when auto-narrowing is enabled. Only those values in the signed * long range get auto-narrowed to tclIntType, while all the * values in the unsigned long range will fit in a long. */ mp_int big; unsigned long scratch, value = 0, numBytes = sizeof(unsigned long); unsigned char *bytes = (unsigned char *) &scratch; UNPACK_BIGNUM(objPtr, big); if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) { while (numBytes-- > 0) { value = (value << CHAR_BIT) | *bytes++; } if (big.sign) { if (value <= 1 + (unsigned long)LONG_MAX) { *longPtr = - (long) value; return TCL_OK; } } else { if (value <= (unsigned long)ULONG_MAX) { *longPtr = (long) value; return TCL_OK; } } } #ifndef TCL_WIDE_INT_IS_LONG tooLarge: #endif if (interp != NULL) { |
︙ | ︙ | |||
2949 2950 2951 2952 2953 2954 2955 | if (objPtr->typePtr == &tclBignumType) { /* * Must check for those bignum values that can fit in a * Tcl_WideInt, even when auto-narrowing is enabled. */ mp_int big; | < < < < | | | | > | | | | | | | | | | | | | < | 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 | if (objPtr->typePtr == &tclBignumType) { /* * Must check for those bignum values that can fit in a * Tcl_WideInt, even when auto-narrowing is enabled. */ mp_int big; Tcl_WideUInt value = 0; unsigned long numBytes = sizeof(Tcl_WideInt); Tcl_WideInt scratch; unsigned char *bytes = (unsigned char *) &scratch; UNPACK_BIGNUM(objPtr, big); if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) { while (numBytes-- > 0) { value = (value << CHAR_BIT) | *bytes++; } if (big.sign) { if (value <= 1 + ~(Tcl_WideUInt)WIDE_MIN) { *wideIntPtr = - (Tcl_WideInt) value; return TCL_OK; } } else { if (value <= (Tcl_WideUInt)WIDE_MAX) { *wideIntPtr = (Tcl_WideInt) value; return TCL_OK; } } } if (interp != NULL) { const char *s = "integer value too large to represent"; Tcl_Obj *msg = Tcl_NewStringObj(s, -1); |
︙ | ︙ | |||
3408 3409 3410 3411 3412 3413 3414 | */ void Tcl_SetBignumObj( Tcl_Obj *objPtr, /* Object to set */ mp_int *bignumValue) /* Value to store */ { | < < < < < | | | | > > > | | | | | | | | | | | | | | | | < | 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 | */ void Tcl_SetBignumObj( Tcl_Obj *objPtr, /* Object to set */ mp_int *bignumValue) /* Value to store */ { Tcl_WideUInt value = 0; unsigned long numBytes = sizeof(Tcl_WideUInt); Tcl_WideUInt scratch; unsigned char *bytes = (unsigned char *) &scratch; if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_SetBignumObj"); } if (mp_to_unsigned_bin_n(bignumValue, bytes, &numBytes) != MP_OKAY) { goto tooLargeForWide; } while (numBytes-- > 0) { value = (value << CHAR_BIT) | *bytes++; } if (value > ((Tcl_WideUInt)WIDE_MAX + bignumValue->sign)) { goto tooLargeForWide; } if (bignumValue->sign) { TclSetIntObj(objPtr, -(Tcl_WideInt)value); } else { TclSetIntObj(objPtr, (Tcl_WideInt)value); } mp_clear(bignumValue); return; tooLargeForWide: TclInvalidateStringRep(objPtr); TclFreeIntRep(objPtr); TclSetBignumIntRep(objPtr, bignumValue); } /* |
︙ | ︙ |
Changes to generic/tclPathObj.c.
︙ | ︙ | |||
556 557 558 559 560 561 562 | Tcl_Obj * TclPathPart( Tcl_Interp *interp, /* Used for error reporting */ Tcl_Obj *pathPtr, /* Path to take dirname of */ Tcl_PathPart portion) /* Requested portion of name */ { | | < < | 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 | Tcl_Obj * TclPathPart( Tcl_Interp *interp, /* Used for error reporting */ Tcl_Obj *pathPtr, /* Path to take dirname of */ Tcl_PathPart portion) /* Requested portion of name */ { if (TclHasIntRep(pathPtr, &fsPathType)) { FsPath *fsPathPtr = PATHOBJ(pathPtr); if (PATHFLAGS(pathPtr) != 0) { switch (portion) { case TCL_PATH_DIRNAME: { /* * Check if the joined-on bit has any directory delimiters in |
︙ | ︙ | |||
1153 1154 1155 1156 1157 1158 1159 | int Tcl_FSConvertToPathType( Tcl_Interp *interp, /* Interpreter in which to store error message * (if necessary). */ Tcl_Obj *pathPtr) /* Object to convert to a valid, current path * type. */ { | < < | | 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 | int Tcl_FSConvertToPathType( Tcl_Interp *interp, /* Interpreter in which to store error message * (if necessary). */ Tcl_Obj *pathPtr) /* Object to convert to a valid, current path * type. */ { /* * While it is bad practice to examine an object's type directly, this is * actually the best thing to do here. The reason is that if we are * converting this object to FsPath type for the first time, we don't need * to worry whether the 'cwd' has changed. On the other hand, if this * object is already of FsPath type, and is a relative path, we do have to * worry about the cwd. If the cwd has changed, we must recompute the * path. */ if (TclHasIntRep(pathPtr, &fsPathType)) { if (TclFSEpochOk(PATHOBJ(pathPtr)->filesystemEpoch)) { return TCL_OK; } TclGetString(pathPtr); Tcl_StoreIntRep(pathPtr, &fsPathType, NULL); } |
︙ | ︙ | |||
1476 1477 1478 1479 1480 1481 1482 | static int MakePathFromNormalized( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *pathPtr) /* The object to convert. */ { FsPath *fsPathPtr; | < | | 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 | static int MakePathFromNormalized( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *pathPtr) /* The object to convert. */ { FsPath *fsPathPtr; if (TclHasIntRep(pathPtr, &fsPathType)) { return TCL_OK; } fsPathPtr = Tcl_Alloc(sizeof(FsPath)); /* * It's a pure normalized absolute path. |
︙ | ︙ | |||
2083 2084 2085 2086 2087 2088 2089 | int TclFSEnsureEpochOk( Tcl_Obj *pathPtr, const Tcl_Filesystem **fsPtrPtr) { FsPath *srcFsPathPtr; | < | | 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 | int TclFSEnsureEpochOk( Tcl_Obj *pathPtr, const Tcl_Filesystem **fsPtrPtr) { FsPath *srcFsPathPtr; if (!TclHasIntRep(pathPtr, &fsPathType)) { return TCL_OK; } srcFsPathPtr = PATHOBJ(pathPtr); /* * Check if the filesystem has changed in some way since this object's |
︙ | ︙ | |||
2142 2143 2144 2145 2146 2147 2148 | void TclFSSetPathDetails( Tcl_Obj *pathPtr, const Tcl_Filesystem *fsPtr, ClientData clientData) { FsPath *srcFsPathPtr; | < | | 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 | void TclFSSetPathDetails( Tcl_Obj *pathPtr, const Tcl_Filesystem *fsPtr, ClientData clientData) { FsPath *srcFsPathPtr; /* * Make sure pathPtr is of the correct type. */ if (!TclHasIntRep(pathPtr, &fsPathType)) { if (SetFsPathFromAny(NULL, pathPtr) != TCL_OK) { return; } } srcFsPathPtr = PATHOBJ(pathPtr); srcFsPathPtr->fsPtr = fsPtr; |
︙ | ︙ | |||
2247 2248 2249 2250 2251 2252 2253 | Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *pathPtr) /* The object to convert. */ { size_t len; FsPath *fsPathPtr; Tcl_Obj *transPtr; char *name; | < | | 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 | Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *pathPtr) /* The object to convert. */ { size_t len; FsPath *fsPathPtr; Tcl_Obj *transPtr; char *name; if (TclHasIntRep(pathPtr, &fsPathType)) { return TCL_OK; } /* * First step is to translate the filename. This is similar to * Tcl_TranslateFilename, but shouldn't convert everything to windows * backslashes on that platform. The current implementation of this piece |
︙ | ︙ | |||
2556 2557 2558 2559 2560 2561 2562 | */ int TclNativePathInFilesystem( Tcl_Obj *pathPtr, ClientData *clientDataPtr) { | < < | | 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 | */ int TclNativePathInFilesystem( Tcl_Obj *pathPtr, ClientData *clientDataPtr) { /* * A special case is required to handle the empty path "". This is a valid * path (i.e. the user should be able to do 'file exists ""' without * throwing an error), but equally the path doesn't exist. Those are the * semantics of Tcl (at present anyway), so we have to abide by them here. */ if (TclHasIntRep(pathPtr, &fsPathType)) { if (pathPtr->bytes != NULL && pathPtr->bytes[0] == '\0') { /* * We reject the empty path "". */ return -1; } |
︙ | ︙ |
Changes to generic/tclProc.c.
︙ | ︙ | |||
325 326 327 328 329 330 331 | * seem to make a lot of sense to verify the number of arguments we * are about to ignore ... * - could be enhanced to handle also non-empty bodies that contain only * comments; however, parsing the body will slow down the compilation * of all procs whose argument list is just _args_ */ | | | 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | * seem to make a lot of sense to verify the number of arguments we * are about to ignore ... * - could be enhanced to handle also non-empty bodies that contain only * comments; however, parsing the body will slow down the compilation * of all procs whose argument list is just _args_ */ if (TclHasIntRep(objv[3], &tclProcBodyType)) { goto done; } procArgs = TclGetString(objv[2]); while (*procArgs == ' ') { procArgs++; |
︙ | ︙ |
Changes to generic/tclStrToD.c.
︙ | ︙ | |||
316 317 318 319 320 321 322 | static char * ShorteningQuickFormat(double, int, int, double, char *, int *); static char * StrictQuickFormat(double, int, int, double, char *, int *); static char * QuickConversion(double, int, int, int, int, int, int, int *, char **); static void CastOutPowersOf2(int *, int *, int *); | | | | | | | | | | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | static char * ShorteningQuickFormat(double, int, int, double, char *, int *); static char * StrictQuickFormat(double, int, int, double, char *, int *); static char * QuickConversion(double, int, int, int, int, int, int, int *, char **); static void CastOutPowersOf2(int *, int *, int *); static char * ShorteningInt64Conversion(Double *, Tcl_WideUInt, int, int, int, int, int, int, int, int, int, int, int, int *, char **); static char * StrictInt64Conversion(Double *, Tcl_WideUInt, int, int, int, int, int, int, int, int, int *, char **); static int ShouldBankerRoundUpPowD(mp_int *, int, int); static int ShouldBankerRoundUpToNextPowD(mp_int *, mp_int *, int, int, mp_int *); static char * ShorteningBignumConversionPowD(Double *dPtr, Tcl_WideUInt bw, int b2, int b5, int m2plus, int m2minus, int m5, int sd, int k, int len, int ilim, int ilim1, int *decpt, char **endPtr); static char * StrictBignumConversionPowD(Double *dPtr, Tcl_WideUInt bw, int b2, int b5, int sd, int k, int len, int ilim, int ilim1, int *decpt, char **endPtr); static int ShouldBankerRoundUp(mp_int *, mp_int *, int); static int ShouldBankerRoundUpToNext(mp_int *, mp_int *, mp_int *, int); static char * ShorteningBignumConversion(Double *dPtr, Tcl_WideUInt bw, int b2, int m2plus, int m2minus, int s2, int s5, int k, int len, int ilim, int ilim1, int *decpt, char **endPtr); static char * StrictBignumConversion(Double *dPtr, Tcl_WideUInt bw, int b2, int s2, int s5, int k, int len, int ilim, int ilim1, int *decpt, char **endPtr); static double BignumToBiasedFrExp(const mp_int *big, int *machexp); static double Pow10TimesFrExp(int exponent, double fraction, int *machexp); |
︙ | ︙ | |||
2343 2344 2345 2346 2347 2348 2349 | * one too high. * *---------------------------------------------------------------------- */ static inline void SetPrecisionLimits( | | | < | < < < < < < | | | | | 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 | * one too high. * *---------------------------------------------------------------------- */ static inline void SetPrecisionLimits( int flags, /* Type of conversion: TCL_DD_SHORTEST, * TCL_DD_E_FMT, TCL_DD_F_FMT. */ int k, /* Floor(log10(number to convert)) */ int *ndigitsPtr, /* IN/OUT: Number of digits requested (will be * adjusted if needed). */ int *iPtr, /* OUT: Maximum number of digits to return. */ int *iLimPtr, /* OUT: Number of digits of significance if * the bignum method is used.*/ int *iLim1Ptr) /* OUT: Number of digits of significance if * the quick method is used. */ { switch (flags & TCL_DD_CONVERSION_TYPE_MASK) { case TCL_DD_E_FORMAT: if (*ndigitsPtr <= 0) { *ndigitsPtr = 1; } *iLimPtr = *iLim1Ptr = *iPtr = *ndigitsPtr; break; case TCL_DD_F_FORMAT: *iPtr = *ndigitsPtr + k + 1; *iLimPtr = *iPtr; *iLim1Ptr = *iPtr - 1; if (*iPtr <= 0) { *iPtr = 1; } break; default: *iLimPtr = *iLim1Ptr = -1; *iPtr = 18; *ndigitsPtr = 0; break; } } /* *---------------------------------------------------------------------- * * BumpUp -- |
︙ | ︙ | |||
2810 2811 2812 2813 2814 2815 2816 | * *---------------------------------------------------------------------- */ static inline char * ShorteningInt64Conversion( Double *dPtr, /* Original number to convert. */ | < < | 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 | * *---------------------------------------------------------------------- */ static inline char * ShorteningInt64Conversion( Double *dPtr, /* Original number to convert. */ Tcl_WideUInt bw, /* Integer significand. */ int b2, int b5, /* Scale factor for the significand in the * numerator. */ int m2plus, int m2minus, int m5, /* Scale factors for 1/2 ulp in the numerator * (will be different if bw == 1. */ int s2, int s5, /* Scale factors for the denominator. */ |
︙ | ︙ | |||
2878 2879 2880 2881 2882 2883 2884 | /* * Does the current digit put us on the low side of the exact value * but within within roundoff of being exact? */ if (b < mplus || (b == mplus | | | 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 | /* * Does the current digit put us on the low side of the exact value * but within within roundoff of being exact? */ if (b < mplus || (b == mplus && (dPtr->w.word1 & 1) == 0)) { /* * Make sure we shouldn't be rounding *up* instead, in case the * next number above is closer. */ if (2 * b > S || (2 * b == S && (digit & 1) != 0)) { ++digit; |
︙ | ︙ | |||
2907 2908 2909 2910 2911 2912 2913 | /* * Does one plus the current digit put us within roundoff of the * number? */ if (b > S - mminus || (b == S - mminus | | | 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 | /* * Does one plus the current digit put us within roundoff of the * number? */ if (b > S - mminus || (b == S - mminus && (dPtr->w.word1 & 1) == 0)) { if (digit == 9) { *s++ = '9'; s = BumpUp(s, retval, &k); break; } ++digit; *s++ = '0' + digit; |
︙ | ︙ | |||
2979 2980 2981 2982 2983 2984 2985 | * *---------------------------------------------------------------------- */ static inline char * StrictInt64Conversion( Double *dPtr, /* Original number to convert. */ | < < | 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 | * *---------------------------------------------------------------------- */ static inline char * StrictInt64Conversion( Double *dPtr, /* Original number to convert. */ Tcl_WideUInt bw, /* Integer significand. */ int b2, int b5, /* Scale factor for the significand in the * numerator. */ int s2, int s5, /* Scale factors for the denominator. */ int k, /* Number of output digits before the decimal * point. */ int len, /* Number of digits to allocate. */ |
︙ | ︙ | |||
3089 3090 3091 3092 3093 3094 3095 | static inline int ShouldBankerRoundUpPowD( mp_int *b, /* Numerator of the fraction. */ int sd, /* Denominator is 2**(sd*DIGIT_BIT). */ int isodd) /* 1 if the digit is odd, 0 if even. */ { int i; | | | 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 | static inline int ShouldBankerRoundUpPowD( mp_int *b, /* Numerator of the fraction. */ int sd, /* Denominator is 2**(sd*DIGIT_BIT). */ int isodd) /* 1 if the digit is odd, 0 if even. */ { int i; static const mp_digit topbit = ((mp_digit)1) << (DIGIT_BIT - 1); if (b->used < sd || (b->dp[sd-1] & topbit) == 0) { return 0; } if (b->dp[sd-1] != topbit) { return 1; } |
︙ | ︙ | |||
3125 3126 3127 3128 3129 3130 3131 | */ static inline int ShouldBankerRoundUpToNextPowD( mp_int *b, /* Numerator of the fraction. */ mp_int *m, /* Numerator of the rounding tolerance. */ int sd, /* Common denominator is 2**(sd*DIGIT_BIT). */ | < < < | 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 | */ static inline int ShouldBankerRoundUpToNextPowD( mp_int *b, /* Numerator of the fraction. */ mp_int *m, /* Numerator of the rounding tolerance. */ int sd, /* Common denominator is 2**(sd*DIGIT_BIT). */ int isodd, /* 1 if the integer significand is odd. */ mp_int *temp) /* Work area for the calculation. */ { int i; /* * Compare B and S-m - which is the same as comparing B+m and S - which we |
︙ | ︙ | |||
3153 3154 3155 3156 3157 3158 3159 | } for (i = sd-1; i >= 0; --i) { /* Check for ==s */ if (temp->dp[i] != 0) { /* > s */ return 1; } } | < < < < | 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 | } for (i = sd-1; i >= 0; --i) { /* Check for ==s */ if (temp->dp[i] != 0) { /* > s */ return 1; } } return isodd; } /* *---------------------------------------------------------------------- * * ShorteningBignumConversionPowD -- |
︙ | ︙ | |||
3186 3187 3188 3189 3190 3191 3192 | * *---------------------------------------------------------------------- */ static inline char * ShorteningBignumConversionPowD( Double *dPtr, /* Original number to convert. */ | < < | 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 | * *---------------------------------------------------------------------- */ static inline char * ShorteningBignumConversionPowD( Double *dPtr, /* Original number to convert. */ Tcl_WideUInt bw, /* Integer significand. */ int b2, int b5, /* Scale factor for the significand in the * numerator. */ int m2plus, int m2minus, int m5, /* Scale factors for 1/2 ulp in the numerator * (will be different if bw == 1). */ int sd, /* Scale factor for the denominator. */ |
︙ | ︙ | |||
3273 3274 3275 3276 3277 3278 3279 | /* * Does the current digit put us on the low side of the exact value * but within within roundoff of being exact? */ r1 = mp_cmp_mag(&b, (m2plus > m2minus)? &mplus : &mminus); if (r1 == MP_LT || (r1 == MP_EQ | | | 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 | /* * Does the current digit put us on the low side of the exact value * but within within roundoff of being exact? */ r1 = mp_cmp_mag(&b, (m2plus > m2minus)? &mplus : &mminus); if (r1 == MP_LT || (r1 == MP_EQ && (dPtr->w.word1 & 1) == 0)) { /* * Make sure we shouldn't be rounding *up* instead, in case the * next number above is closer. */ if (ShouldBankerRoundUpPowD(&b, sd, digit&1)) { ++digit; |
︙ | ︙ | |||
3301 3302 3303 3304 3305 3306 3307 | } /* * Does one plus the current digit put us within roundoff of the * number? */ | | | 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 | } /* * Does one plus the current digit put us within roundoff of the * number? */ if (ShouldBankerRoundUpToNextPowD(&b, &mminus, sd, dPtr->w.word1 & 1, &temp)) { if (digit == 9) { *s++ = '9'; s = BumpUp(s, retval, &k); break; } ++digit; |
︙ | ︙ | |||
3379 3380 3381 3382 3383 3384 3385 | * *---------------------------------------------------------------------- */ static inline char * StrictBignumConversionPowD( Double *dPtr, /* Original number to convert. */ | < < < < | 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 | * *---------------------------------------------------------------------- */ static inline char * StrictBignumConversionPowD( Double *dPtr, /* Original number to convert. */ Tcl_WideUInt bw, /* Integer significand. */ int b2, int b5, /* Scale factor for the significand in the * numerator. */ int sd, /* Scale factor for the denominator. */ int k, /* Number of output digits before the decimal * point. */ int len, /* Number of digits to allocate. */ int ilim, /* Number of digits to convert if b >= s */ int ilim1, /* Number of digits to convert if b < s */ int *decpt, /* OUTPUT: Position of the decimal point. */ char **endPtr) /* OUTPUT: Position of the terminal '\0' at * the end of the returned string. */ { char *retval = Tcl_Alloc(len + 1); /* Output buffer. */ mp_int b; /* Numerator of the fraction being * converted. */ mp_digit digit; /* Current output digit. */ char *s = retval; /* Cursor in the output buffer. */ int i; /* Index in the output buffer. */ /* * b = bw * 2**b2 * 5**b5 */ TclInitBignumFromWideUInt(&b, bw); MulPow5(&b, b5, &b); mp_mul_2d(&b, b2, &b); /* * Adjust if the logarithm was guessed wrong. */ if (b.used <= sd) { mp_mul_d(&b, 10, &b); ilim = ilim1; --k; } /* * Loop through the digits. Do division and mod by s == 2**(sd*DIGIT_BIT) * by mp_digit extraction. */ i = 1; |
︙ | ︙ | |||
3469 3470 3471 3472 3473 3474 3475 | } /* * Endgame - store the location of the decimal point and the end of the * string. */ | | | 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 | } /* * Endgame - store the location of the decimal point and the end of the * string. */ mp_clear(&b); *s = '\0'; *decpt = k; if (endPtr) { *endPtr = s; } return retval; } |
︙ | ︙ | |||
3533 3534 3535 3536 3537 3538 3539 | static inline int ShouldBankerRoundUpToNext( mp_int *b, /* Remainder from the division that produced * the last digit. */ mp_int *m, /* Numerator of the rounding tolerance. */ mp_int *S, /* Denominator. */ | < < < | < > > | | > < < < | < | 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 | static inline int ShouldBankerRoundUpToNext( mp_int *b, /* Remainder from the division that produced * the last digit. */ mp_int *m, /* Numerator of the rounding tolerance. */ mp_int *S, /* Denominator. */ int isodd) /* 1 if the integer significand is odd. */ { int r; mp_int temp; /* * Compare b and S-m: this is the same as comparing B+m and S. */ mp_init(&temp); mp_add(b, m, &temp); r = mp_cmp_mag(&temp, S); mp_clear(&temp); switch(r) { case MP_LT: return 0; case MP_EQ: return isodd; case MP_GT: return 1; } Tcl_Panic("in ShouldBankerRoundUpToNext, trichotomy fails!"); return 0; } |
︙ | ︙ | |||
3584 3585 3586 3587 3588 3589 3590 | * *---------------------------------------------------------------------- */ static inline char * ShorteningBignumConversion( Double *dPtr, /* Original number being converted. */ | < < | 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 | * *---------------------------------------------------------------------- */ static inline char * ShorteningBignumConversion( Double *dPtr, /* Original number being converted. */ Tcl_WideUInt bw, /* Integer significand and exponent. */ int b2, /* Scale factor for the significand. */ int m2plus, int m2minus, /* Scale factors for 1/2 ulp in numerator. */ int s2, int s5, /* Scale factors for denominator. */ int k, /* Guessed position of the decimal point. */ int len, /* Size of the digit buffer to allocate. */ int ilim, /* Number of digits to convert if b >= s */ int ilim1, /* Number of digits to convert if b < s */ int *decpt, /* OUTPUT: Position of the decimal point. */ char **endPtr) /* OUTPUT: Pointer to the end of the number */ { char *retval = Tcl_Alloc(len+1); /* Buffer of digits to return. */ char *s = retval; /* Cursor in the return value. */ mp_int b; /* Numerator of the result. */ mp_int mminus; /* 1/2 ulp below the result. */ mp_int mplus; /* 1/2 ulp above the result. */ mp_int S; /* Denominator of the result. */ mp_int dig; /* Current digit of the result. */ int digit; /* Current digit of the result. */ int minit = 1; /* Fudge factor for when we misguess k. */ int i; int r1; /* * b = bw * 2**b2 * 5**b5 * S = 2**s2 * 5*s5 |
︙ | ︙ | |||
3641 3642 3643 3644 3645 3646 3647 | mp_init_set_int(&mminus, minit); mp_mul_2d(&mminus, m2minus, &mminus); if (m2plus > m2minus) { mp_init_copy(&mplus, &mminus); mp_mul_2d(&mplus, m2plus-m2minus, &mplus); } | < | < | | | 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 | mp_init_set_int(&mminus, minit); mp_mul_2d(&mminus, m2minus, &mminus); if (m2plus > m2minus) { mp_init_copy(&mplus, &mminus); mp_mul_2d(&mplus, m2plus-m2minus, &mplus); } /* * Loop through the digits. */ mp_init(&dig); i = 1; for (;;) { mp_div(&b, &S, &dig, &b); if (dig.used > 1 || dig.dp[0] >= 10) { Tcl_Panic("wrong digit!"); } digit = dig.dp[0]; /* * Does the current digit leave us with a remainder small enough to * round to it? */ r1 = mp_cmp_mag(&b, (m2plus > m2minus)? &mplus : &mminus); if (r1 == MP_LT || (r1 == MP_EQ && (dPtr->w.word1 & 1) == 0)) { mp_mul_2d(&b, 1, &b); if (ShouldBankerRoundUp(&b, &S, digit&1)) { ++digit; if (digit == 10) { *s++ = '9'; s = BumpUp(s, retval, &k); break; } } *s++ = '0' + digit; break; } /* * Does the current digit leave us with a remainder large enough to * commit to rounding up to the next higher digit? */ if (ShouldBankerRoundUpToNext(&b, &mminus, &S, dPtr->w.word1 & 1)) { ++digit; if (digit == 10) { *s++ = '9'; s = BumpUp(s, retval, &k); break; } *s++ = '0' + digit; |
︙ | ︙ | |||
3770 3771 3772 3773 3774 3775 3776 | * Endgame - store the location of the decimal point and the end of the * string. */ if (m2plus > m2minus) { mp_clear(&mplus); } | | | 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 | * Endgame - store the location of the decimal point and the end of the * string. */ if (m2plus > m2minus) { mp_clear(&mplus); } mp_clear_multi(&b, &mminus, &dig, &S, NULL); *s = '\0'; *decpt = k; if (endPtr) { *endPtr = s; } return retval; } |
︙ | ︙ | |||
3800 3801 3802 3803 3804 3805 3806 | * *---------------------------------------------------------------------- */ static inline char * StrictBignumConversion( Double *dPtr, /* Original number being converted. */ | < < | | 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 | * *---------------------------------------------------------------------- */ static inline char * StrictBignumConversion( Double *dPtr, /* Original number being converted. */ Tcl_WideUInt bw, /* Integer significand and exponent. */ int b2, /* Scale factor for the significand. */ int s2, int s5, /* Scale factors for denominator. */ int k, /* Guessed position of the decimal point. */ int len, /* Size of the digit buffer to allocate. */ int ilim, /* Number of digits to convert if b >= s */ int ilim1, /* Number of digits to convert if b < s */ int *decpt, /* OUTPUT: Position of the decimal point. */ char **endPtr) /* OUTPUT: Pointer to the end of the number */ { char *retval = Tcl_Alloc(len+1); /* Buffer of digits to return. */ char *s = retval; /* Cursor in the return value. */ mp_int b; /* Numerator of the result. */ mp_int S; /* Denominator of the result. */ mp_int dig; /* Current digit of the result. */ int digit; /* Current digit of the result. */ int g; /* Size of the current digit ground. */ int i, j; /* * b = bw * 2**b2 * 5**b5 * S = 2**s2 * 5*s5 */ mp_init_multi(&dig, NULL); TclInitBignumFromWideUInt(&b, bw); mp_mul_2d(&b, b2, &b); mp_init_set_int(&S, 1); MulPow5(&S, s5, &S); mp_mul_2d(&S, s2, &S); /* * Handle the case where we guess the position of the decimal point wrong. |
︙ | ︙ | |||
3934 3935 3936 3937 3938 3939 3940 | ++s; /* * Endgame - store the location of the decimal point and the end of the * string. */ | | | 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 | ++s; /* * Endgame - store the location of the decimal point and the end of the * string. */ mp_clear_multi(&b, &S, &dig, NULL); *s = '\0'; *decpt = k; if (endPtr) { *endPtr = s; } return retval; } |
︙ | ︙ | |||
3970 3971 3972 3973 3974 3975 3976 | * according to the 'flags' argument. Valid values for 'flags' include: * TCL_DD_SHORTEST - This is the default for floating point conversion. * It constructs the shortest string of * digits that will reconvert to the given number when scanned. * For floating point numbers that are exactly between two * decimal numbers, it resolves using the 'round to even' rule. * With this value, the 'ndigits' parameter is ignored. | < < < < < < < < < | 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 | * according to the 'flags' argument. Valid values for 'flags' include: * TCL_DD_SHORTEST - This is the default for floating point conversion. * It constructs the shortest string of * digits that will reconvert to the given number when scanned. * For floating point numbers that are exactly between two * decimal numbers, it resolves using the 'round to even' rule. * With this value, the 'ndigits' parameter is ignored. * TCL_DD_E_FORMAT - This value is used to prepare numbers for %e format * conversion. It constructs a string of at most 'ndigits' digits, * choosing the one that is closest to the given number (and * resolving ties with 'round to even'). It is allowed to return * fewer than 'ndigits' if the number converts exactly; if the * TCL_DD_E_FORMAT|TCL_DD_SHORTEN_FLAG is supplied instead, it * also returns fewer digits if the shorter string will still |
︙ | ︙ | |||
4028 4029 4030 4031 4032 4033 4034 | int flags, /* Conversion flags. */ int *decpt, /* OUTPUT: Position of the decimal point. */ int *sign, /* OUTPUT: 1 if the result is negative. */ char **endPtr) /* OUTPUT: If not NULL, receives a pointer to * one character beyond the end of the * returned string. */ { | < < < < | 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 | int flags, /* Conversion flags. */ int *decpt, /* OUTPUT: Position of the decimal point. */ int *sign, /* OUTPUT: 1 if the result is negative. */ char **endPtr) /* OUTPUT: If not NULL, receives a pointer to * one character beyond the end of the * returned string. */ { Double d; /* Union for deconstructing doubles. */ Tcl_WideUInt bw; /* Integer significand. */ int be; /* Power of 2 by which b must be multiplied */ int bbits; /* Number of bits needed to represent b. */ int denorm; /* Flag == 1 iff the input number was * denormalized. */ int k; /* Estimate of floor(log10(d)). */ |
︙ | ︙ | |||
4099 4100 4101 4102 4103 4104 4105 | ComputeScale(be, k, &b2, &b5, &s2, &s5); /* * Correct an incorrect caller-supplied 'ndigits'. Also determine: * i = The maximum number of decimal digits that will be returned in the * formatted string. This is k + 1 + ndigits for F format, 18 for | | | | | | | 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 | ComputeScale(be, k, &b2, &b5, &s2, &s5); /* * Correct an incorrect caller-supplied 'ndigits'. Also determine: * i = The maximum number of decimal digits that will be returned in the * formatted string. This is k + 1 + ndigits for F format, 18 for * shortest, and ndigits for E format. * ilim = The number of significant digits to convert if k has been * guessed correctly. This is -1 for shortest (which * stop when all significance has been lost), 'ndigits' for E * format, and 'k + 1 + ndigits' for F format. * ilim1 = The minimum number of significant digits to convert if k has * been guessed 1 too high. This, too, is -1 for shortest, * and 'ndigits' for E format, but it's 'ndigits-1' for F * format. */ SetPrecisionLimits(flags, k, &ndigits, &i, &ilim, &ilim1); /* * Try to do low-precision conversion in floating point rather than * resorting to expensive multiprecision arithmetic. */ if (ilim >= 0 && ilim <= QUICK_MAX && !(flags & TCL_DD_NO_QUICK)) { |
︙ | ︙ | |||
4183 4184 4185 4186 4187 4188 4189 | * If 10*2**s2*5**s5 == 2**(s2+1)+5**(s5+1) fits in a 64-bit word, * then all our intermediate calculations can be done using exact * 64-bit arithmetic with no need for expensive multiprecision * operations. (This will be true for all numbers in the range * [1.0e-3 .. 1.0e+24]). */ | | | | | 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 | * If 10*2**s2*5**s5 == 2**(s2+1)+5**(s5+1) fits in a 64-bit word, * then all our intermediate calculations can be done using exact * 64-bit arithmetic with no need for expensive multiprecision * operations. (This will be true for all numbers in the range * [1.0e-3 .. 1.0e+24]). */ return ShorteningInt64Conversion(&d, bw, b2, b5, m2plus, m2minus, m5, s2, s5, k, len, ilim, ilim1, decpt, endPtr); } else if (s5 == 0) { /* * The denominator is a power of 2, so we can replace division by * digit shifts. First we round up s2 to a multiple of DIGIT_BIT, * and adjust m2 and b2 accordingly. Then we launch into a version * of the comparison that's specialized for the 'power of mp_digit * in the denominator' case. */ if (s2 % DIGIT_BIT != 0) { int delta = DIGIT_BIT - (s2 % DIGIT_BIT); b2 += delta; m2plus += delta; m2minus += delta; s2 += delta; } return ShorteningBignumConversionPowD(&d, bw, b2, b5, m2plus, m2minus, m5, s2/DIGIT_BIT, k, len, ilim, ilim1, decpt, endPtr); } else { /* * Alas, there's no helpful special case; use full-up bignum * arithmetic for the conversion. */ return ShorteningBignumConversion(&d, bw, b2, m2plus, m2minus, s2, s5, k, len, ilim, ilim1, decpt, endPtr); } } else { /* * Non-shortening conversion. */ |
︙ | ︙ | |||
4239 4240 4241 4242 4243 4244 4245 | /* * If 10*2**s2*5**s5 == 2**(s2+1)+5**(s5+1) fits in a 64-bit word, * then all our intermediate calculations can be done using exact * 64-bit arithmetic with no need for expensive multiprecision * operations. */ | | | | | 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 | /* * If 10*2**s2*5**s5 == 2**(s2+1)+5**(s5+1) fits in a 64-bit word, * then all our intermediate calculations can be done using exact * 64-bit arithmetic with no need for expensive multiprecision * operations. */ return StrictInt64Conversion(&d, bw, b2, b5, s2, s5, k, len, ilim, ilim1, decpt, endPtr); } else if (s5 == 0) { /* * The denominator is a power of 2, so we can replace division by * digit shifts. First we round up s2 to a multiple of DIGIT_BIT, * and adjust m2 and b2 accordingly. Then we launch into a version * of the comparison that's specialized for the 'power of mp_digit * in the denominator' case. */ if (s2 % DIGIT_BIT != 0) { int delta = DIGIT_BIT - (s2 % DIGIT_BIT); b2 += delta; s2 += delta; } return StrictBignumConversionPowD(&d, bw, b2, b5, s2/DIGIT_BIT, k, len, ilim, ilim1, decpt, endPtr); } else { /* * There are no helpful special cases, but at least we know in * advance how many digits we will convert. We can run the * conversion in steps of DIGIT_GROUP digits, so as to have many * fewer mp_int divisions. */ return StrictBignumConversion(&d, bw, b2, s2, s5, k, len, ilim, ilim1, decpt, endPtr); } } } /* *---------------------------------------------------------------------- |
︙ | ︙ |
Changes to generic/tclStubInit.c.
︙ | ︙ | |||
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | #undef Tcl_FindExecutable #undef Tcl_SetExitProc #undef Tcl_SetPanicProc #undef TclpGetPid #undef TclSockMinimumBuffers #undef Tcl_SetIntObj #undef TclStaticPackage #define TclStaticPackage Tcl_StaticPackage #ifdef TCL_MEM_DEBUG # define Tcl_Alloc TclpAlloc # define Tcl_Free TclpFree # define Tcl_Realloc TclpRealloc # undef Tcl_AttemptAlloc # define Tcl_AttemptAlloc TclpAlloc # undef Tcl_AttemptRealloc # define Tcl_AttemptRealloc TclpRealloc #endif #ifdef _WIN32 # define TclUnixWaitForFile 0 # define TclUnixCopyFile 0 # define TclUnixOpenTemporaryFile 0 # define TclpIsAtty 0 #elif defined(__CYGWIN__) # define TclpIsAtty TclPlatIsAtty static void doNothing(void) { /* dummy implementation, no need to do anything */ } # define TclWinAddProcess (void (*) (void *, size_t)) doNothing # define TclWinFlushDirtyChannels doNothing | > > > | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | #undef Tcl_FindExecutable #undef Tcl_SetExitProc #undef Tcl_SetPanicProc #undef TclpGetPid #undef TclSockMinimumBuffers #undef Tcl_SetIntObj #undef TclStaticPackage #undef TclBNInitBignumFromLong #undef Tcl_BackgroundError #define TclStaticPackage Tcl_StaticPackage #ifdef TCL_MEM_DEBUG # define Tcl_Alloc TclpAlloc # define Tcl_Free TclpFree # define Tcl_Realloc TclpRealloc # undef Tcl_AttemptAlloc # define Tcl_AttemptAlloc TclpAlloc # undef Tcl_AttemptRealloc # define Tcl_AttemptRealloc TclpRealloc #endif #ifdef _WIN32 # define TclUnixWaitForFile 0 # define TclUnixCopyFile 0 # define TclUnixOpenTemporaryFile 0 # define TclpIsAtty 0 #elif defined(__CYGWIN__) # define TclpIsAtty TclPlatIsAtty static void doNothing(void) { /* dummy implementation, no need to do anything */ } # define TclWinAddProcess (void (*) (void *, size_t)) doNothing # define TclWinFlushDirtyChannels doNothing |
︙ | ︙ | |||
721 722 723 724 725 726 727 | TclBN_mp_sub_d, /* 43 */ TclBN_mp_to_unsigned_bin, /* 44 */ TclBN_mp_to_unsigned_bin_n, /* 45 */ TclBN_mp_toradix_n, /* 46 */ TclBN_mp_unsigned_bin_size, /* 47 */ TclBN_mp_xor, /* 48 */ TclBN_mp_zero, /* 49 */ | | | | | | | | | | | | | 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 | TclBN_mp_sub_d, /* 43 */ TclBN_mp_to_unsigned_bin, /* 44 */ TclBN_mp_to_unsigned_bin_n, /* 45 */ TclBN_mp_toradix_n, /* 46 */ TclBN_mp_unsigned_bin_size, /* 47 */ TclBN_mp_xor, /* 48 */ TclBN_mp_zero, /* 49 */ 0, /* 50 */ 0, /* 51 */ 0, /* 52 */ 0, /* 53 */ 0, /* 54 */ 0, /* 55 */ 0, /* 56 */ 0, /* 57 */ 0, /* 58 */ 0, /* 59 */ 0, /* 60 */ TclBN_mp_init_set_int, /* 61 */ TclBN_mp_set_int, /* 62 */ TclBN_mp_cnt_lsb, /* 63 */ 0, /* 64 */ 0, /* 65 */ 0, /* 66 */ TclBN_mp_expt_d_ex, /* 67 */ |
︙ | ︙ |
Changes to generic/tclTest.c.
︙ | ︙ | |||
1698 1699 1700 1701 1702 1703 1704 | * * Usage: * testdoubledigits fpval ndigits type ?shorten" * * Parameters: * fpval - Floating-point value to format. * ndigits - Digit count to request from Tcl_DoubleDigits | | < < | 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 | * * Usage: * testdoubledigits fpval ndigits type ?shorten" * * Parameters: * fpval - Floating-point value to format. * ndigits - Digit count to request from Tcl_DoubleDigits * type - One of 'shortest', 'e', 'f' * shorten - Indicates that the 'shorten' flag should be passed in. * *----------------------------------------------------------------------------- */ static int TestdoubledigitsObjCmd(void *unused, /* NULL */ Tcl_Interp* interp, /* Tcl interpreter */ int objc, /* Parameter count */ Tcl_Obj* const objv[]) /* Parameter vector */ { static const char* options[] = { "shortest", "e", "f", NULL }; static const int types[] = { TCL_DD_SHORTEST, TCL_DD_E_FORMAT, TCL_DD_F_FORMAT }; const Tcl_ObjType* doubleType; double d; int status; |
︙ | ︙ |
Changes to generic/tclTomMath.decls.
︙ | ︙ | |||
171 172 173 174 175 176 177 | declare 48 { int TclBN_mp_xor(const mp_int *a, const mp_int *b, mp_int *c) } declare 49 { void TclBN_mp_zero(mp_int *a) } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | declare 48 { int TclBN_mp_xor(const mp_int *a, const mp_int *b, mp_int *c) } declare 49 { void TclBN_mp_zero(mp_int *a) } declare 61 { int TclBN_mp_init_set_int(mp_int *a, unsigned long i) } declare 62 { int TclBN_mp_set_int(mp_int *a, unsigned long i) } declare 63 { |
︙ | ︙ | |||
238 239 240 241 242 243 244 | # Added in libtommath 1.0 declare 67 { int TclBN_mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) } # Added in libtommath 1.0.1 declare 68 { | | | | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | # Added in libtommath 1.0 declare 67 { int TclBN_mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) } # Added in libtommath 1.0.1 declare 68 { int TclBN_mp_set_long_long(mp_int *a, unsigned TCL_WIDE_INT_TYPE i) } declare 69 { unsigned TCL_WIDE_INT_TYPE TclBN_mp_get_long_long(const mp_int *a) } declare 70 { int TclBN_mp_set_long(mp_int *a, unsigned long i) } declare 71 { unsigned long TclBN_mp_get_long(const mp_int *a) } |
︙ | ︙ |
Changes to generic/tclTomMath.h.
1 2 3 4 5 6 7 8 9 | /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * | | < | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * * SPDX-License-Identifier: Unlicense */ #ifndef BN_H_ #define BN_H_ #include "tclTomMathDecls.h" #ifndef MODULE_SCOPE #define MODULE_SCOPE extern #endif #ifdef __cplusplus extern "C" { #endif /* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */ #if defined(_WIN32) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__) # define MP_32BIT #endif /* detect 64-bit mode if possible */ #if defined(NEVER) # if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT)) # if defined(__GNUC__) |
︙ | ︙ | |||
106 107 108 109 110 111 112 | # define MP_28BIT # endif #endif /* otherwise the bits per digit is calculated automatically from the size of a mp_digit */ #ifndef DIGIT_BIT # define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */ | < < < > | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | # define MP_28BIT # endif #endif /* otherwise the bits per digit is calculated automatically from the size of a mp_digit */ #ifndef DIGIT_BIT # define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */ #endif #define MP_DIGIT_BIT DIGIT_BIT #define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) #define MP_DIGIT_MAX MP_MASK /* equalities */ #define MP_LT -1 /* less than */ #define MP_EQ 0 /* equal to */ #define MP_GT 1 /* greater than */ #define MP_ZPOS 0 /* positive integer */ #define MP_NEG 1 /* negative */ #define MP_OKAY 0 /* ok result */ #define MP_MEM -2 /* out of mem */ #define MP_VAL -3 /* invalid input */ #define MP_RANGE MP_VAL #define MP_ITER -4 /* Max. iterations reached */ #define MP_YES 1 /* yes response */ #define MP_NO 0 /* no response */ /* Primality generation flags */ #define LTM_PRIME_BBS 0x0001 /* BBS style prime */ #define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ |
︙ | ︙ | |||
174 175 176 177 178 179 180 | int used, alloc, sign; mp_digit *dp; }; /* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */ typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); | < < < < < | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | int used, alloc, sign; mp_digit *dp; }; /* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */ typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); /* error code to char* string */ const char *mp_error_to_string(int code); /* ---> init and deinit bignum functions <--- */ /* init a bignum */ /* int mp_init(mp_int *a); |
︙ | ︙ | |||
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 | void mp_zero(mp_int *a); */ /* set to a digit */ /* void mp_set(mp_int *a, mp_digit b); */ /* set a 32-bit const */ /* int mp_set_int(mp_int *a, unsigned long b); */ /* set a platform dependent unsigned long value */ /* int mp_set_long(mp_int *a, unsigned long b); */ /* set a platform dependent unsigned long long value */ /* int mp_set_long_long(mp_int *a, unsigned long long b); */ /* get a 32-bit value */ /* unsigned long mp_get_int(const mp_int *a); */ /* get a platform dependent unsigned long value */ | > > > > > > > > > > | 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 | void mp_zero(mp_int *a); */ /* set to a digit */ /* void mp_set(mp_int *a, mp_digit b); */ /* set a double */ /* int mp_set_double(mp_int *a, double b); */ /* set a 32-bit const */ /* int mp_set_int(mp_int *a, unsigned long b); */ /* set a platform dependent unsigned long value */ /* int mp_set_long(mp_int *a, unsigned long b); */ /* set a platform dependent unsigned long long value */ /* int mp_set_long_long(mp_int *a, unsigned long long b); */ /* get a double */ /* double mp_get_double(const mp_int *a); */ /* get a 32-bit value */ /* unsigned long mp_get_int(const mp_int *a); */ /* get a platform dependent unsigned long value */ |
︙ | ︙ | |||
353 354 355 356 357 358 359 | /* Counts the number of lsbs which are zero before the first zero bit */ /* int mp_cnt_lsb(const mp_int *a); */ /* I Love Earth! */ | | > > > > | > | < > > > > > > > > | 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | /* Counts the number of lsbs which are zero before the first zero bit */ /* int mp_cnt_lsb(const mp_int *a); */ /* I Love Earth! */ /* makes a pseudo-random mp_int of a given size */ /* int mp_rand(mp_int *a, int digits); */ /* makes a pseudo-random small int of a given size */ /* int mp_rand_digit(mp_digit *r); */ #ifdef MP_PRNG_ENABLE_LTM_RNG /* A last resort to provide random data on systems without any of the other * implemented ways to gather entropy. * It is compatible with `rng_get_bytes()` from libtomcrypt so you could * provide that one and then set `ltm_rng = rng_get_bytes;` */ extern unsigned long (*ltm_rng)(unsigned char *out, unsigned long outlen, void (*callback)(void)); extern void (*ltm_rng_callback)(void); #endif /* ---> binary operations <--- */ /* c = a XOR b */ /* int mp_xor(const mp_int *a, const mp_int *b, mp_int *c); */ /* c = a OR b */ /* int mp_or(const mp_int *a, const mp_int *b, mp_int *c); */ /* c = a AND b */ /* int mp_and(const mp_int *a, const mp_int *b, mp_int *c); */ /* Checks the bit at position b and returns MP_YES if the bit is 1, MP_NO if it is 0 and MP_VAL in case of error */ /* int mp_get_bit(const mp_int *a, int b); */ /* c = a XOR b (two complement) */ /* int mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c); */ /* c = a OR b (two complement) */ |
︙ | ︙ | |||
576 577 578 579 580 581 582 583 584 585 586 587 588 589 | int mp_is_square(const mp_int *arg, int *ret); */ /* computes the jacobi c = (a | n) (or Legendre if b is prime) */ /* int mp_jacobi(const mp_int *a, const mp_int *n, int *c); */ /* used to setup the Barrett reduction for a given modulus b */ /* int mp_reduce_setup(mp_int *a, const mp_int *b); */ /* Barrett Reduction, computes a (mod b) with a precomputed value c | > > > > > | 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 | int mp_is_square(const mp_int *arg, int *ret); */ /* computes the jacobi c = (a | n) (or Legendre if b is prime) */ /* int mp_jacobi(const mp_int *a, const mp_int *n, int *c); */ /* computes the Kronecker symbol c = (a | p) (like jacobi() but with {a,p} in Z */ /* int mp_kronecker(const mp_int *a, const mp_int *p, int *c); */ /* used to setup the Barrett reduction for a given modulus b */ /* int mp_reduce_setup(mp_int *a, const mp_int *b); */ /* Barrett Reduction, computes a (mod b) with a precomputed value c |
︙ | ︙ | |||
698 699 700 701 702 703 704 | /* This gives [for a given bit size] the number of trials required * such that Miller-Rabin gives a prob of failure lower than 2^-96 */ /* int mp_prime_rabin_miller_trials(int size); */ | > > > > > > > > > > > > > > | | > > > > > > > | 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 | /* This gives [for a given bit size] the number of trials required * such that Miller-Rabin gives a prob of failure lower than 2^-96 */ /* int mp_prime_rabin_miller_trials(int size); */ /* performs one strong Lucas-Selfridge test of "a". * Sets result to 0 if composite or 1 if probable prime */ /* int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result); */ /* performs one Frobenius test of "a" as described by Paul Underwood. * Sets result to 0 if composite or 1 if probable prime */ /* int mp_prime_frobenius_underwood(const mp_int *N, int *result); */ /* performs t random rounds of Miller-Rabin on "a" additional to * bases 2 and 3. Also performs an initial sieve of trial * division. Determines if "a" is prime with probability * of error no more than (1/4)**t. * Both a strong Lucas-Selfridge to complete the BPSW test * and a separate Frobenius test are available at compile time. * With t<0 a deterministic test is run for primes up to * 318665857834031151167461. With t<13 (abs(t)-13) additional * tests with sequential small primes are run starting at 43. * Is Fips 186.4 compliant if called with t as computed by * mp_prime_rabin_miller_trials(); * * Sets result to 1 if probably prime, 0 otherwise */ /* int mp_prime_is_prime(const mp_int *a, int t, int *result); */ |
︙ | ︙ |
Changes to generic/tclTomMathDecls.h.
︙ | ︙ | |||
47 48 49 50 51 52 53 | /* Rename the global symbols in libtommath to avoid linkage conflicts */ #define KARATSUBA_MUL_CUTOFF TclBNKaratsubaMulCutoff #define KARATSUBA_SQR_CUTOFF TclBNKaratsubaSqrCutoff #define TOOM_MUL_CUTOFF TclBNToomMulCutoff #define TOOM_SQR_CUTOFF TclBNToomSqrCutoff | < < < | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /* Rename the global symbols in libtommath to avoid linkage conflicts */ #define KARATSUBA_MUL_CUTOFF TclBNKaratsubaMulCutoff #define KARATSUBA_SQR_CUTOFF TclBNKaratsubaSqrCutoff #define TOOM_MUL_CUTOFF TclBNToomMulCutoff #define TOOM_SQR_CUTOFF TclBNToomSqrCutoff #define mp_add TclBN_mp_add #define mp_add_d TclBN_mp_add_d #define mp_and TclBN_mp_and #define mp_clamp TclBN_mp_clamp #define mp_clear TclBN_mp_clear #define mp_clear_multi TclBN_mp_clear_multi #define mp_cmp TclBN_mp_cmp |
︙ | ︙ | |||
80 81 82 83 84 85 86 | #define mp_grow TclBN_mp_grow #define mp_init TclBN_mp_init #define mp_init_copy TclBN_mp_init_copy #define mp_init_multi TclBN_mp_init_multi #define mp_init_set TclBN_mp_init_set #define mp_init_set_int TclBN_mp_init_set_int #define mp_init_size TclBN_mp_init_size | < < | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | #define mp_grow TclBN_mp_grow #define mp_init TclBN_mp_init #define mp_init_copy TclBN_mp_init_copy #define mp_init_multi TclBN_mp_init_multi #define mp_init_set TclBN_mp_init_set #define mp_init_set_int TclBN_mp_init_set_int #define mp_init_size TclBN_mp_init_size #define mp_lshd TclBN_mp_lshd #define mp_mod TclBN_mp_mod #define mp_mod_2d TclBN_mp_mod_2d #define mp_mul TclBN_mp_mul #define mp_mul_2 TclBN_mp_mul_2 #define mp_mul_2d TclBN_mp_mul_2d #define mp_mul_d TclBN_mp_mul_d |
︙ | ︙ | |||
109 110 111 112 113 114 115 | #define mp_sub_d TclBN_mp_sub_d #define mp_tc_and TclBN_mp_tc_and #define mp_tc_div_2d TclBN_mp_tc_div_2d #define mp_tc_or TclBN_mp_tc_or #define mp_tc_xor TclBN_mp_tc_xor #define mp_to_unsigned_bin TclBN_mp_to_unsigned_bin #define mp_to_unsigned_bin_n TclBN_mp_to_unsigned_bin_n | < < | > > > > > > > > | | | | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | #define mp_sub_d TclBN_mp_sub_d #define mp_tc_and TclBN_mp_tc_and #define mp_tc_div_2d TclBN_mp_tc_div_2d #define mp_tc_or TclBN_mp_tc_or #define mp_tc_xor TclBN_mp_tc_xor #define mp_to_unsigned_bin TclBN_mp_to_unsigned_bin #define mp_to_unsigned_bin_n TclBN_mp_to_unsigned_bin_n #define mp_toradix_n TclBN_mp_toradix_n #define mp_unsigned_bin_size TclBN_mp_unsigned_bin_size #define mp_xor TclBN_mp_xor #define mp_zero TclBN_mp_zero MODULE_SCOPE void bn_reverse(unsigned char *s, int len); MODULE_SCOPE int fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs); MODULE_SCOPE int fast_s_mp_sqr(const mp_int *a, mp_int *b); MODULE_SCOPE int mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c); MODULE_SCOPE int mp_karatsuba_sqr(const mp_int *a, mp_int *b); MODULE_SCOPE int mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c); MODULE_SCOPE int mp_toom_sqr(const mp_int *a, mp_int *b); MODULE_SCOPE int s_mp_add(const mp_int *a, const mp_int *b, mp_int *c); MODULE_SCOPE int s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs); MODULE_SCOPE int s_mp_sqr(const mp_int *a, mp_int *b); MODULE_SCOPE int s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c); #undef TCL_STORAGE_CLASS #ifdef BUILD_tcl # define TCL_STORAGE_CLASS DLLEXPORT #else # ifdef USE_TCL_STUBS # define TCL_STORAGE_CLASS |
︙ | ︙ | |||
267 268 269 270 271 272 273 | /* 47 */ EXTERN int TclBN_mp_unsigned_bin_size(const mp_int *a); /* 48 */ EXTERN int TclBN_mp_xor(const mp_int *a, const mp_int *b, mp_int *c); /* 49 */ EXTERN void TclBN_mp_zero(mp_int *a); | | < | < < | < | < < | < | < < | < | < < | < < | < | < < | > | | 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | /* 47 */ EXTERN int TclBN_mp_unsigned_bin_size(const mp_int *a); /* 48 */ EXTERN int TclBN_mp_xor(const mp_int *a, const mp_int *b, mp_int *c); /* 49 */ EXTERN void TclBN_mp_zero(mp_int *a); /* Slot 50 is reserved */ /* Slot 51 is reserved */ /* Slot 52 is reserved */ /* Slot 53 is reserved */ /* Slot 54 is reserved */ /* Slot 55 is reserved */ /* Slot 56 is reserved */ /* Slot 57 is reserved */ /* Slot 58 is reserved */ /* Slot 59 is reserved */ /* Slot 60 is reserved */ /* 61 */ EXTERN int TclBN_mp_init_set_int(mp_int *a, unsigned long i); /* 62 */ EXTERN int TclBN_mp_set_int(mp_int *a, unsigned long i); /* 63 */ EXTERN int TclBN_mp_cnt_lsb(const mp_int *a); /* Slot 64 is reserved */ /* Slot 65 is reserved */ /* Slot 66 is reserved */ /* 67 */ EXTERN int TclBN_mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast); /* 68 */ EXTERN int TclBN_mp_set_long_long(mp_int *a, unsigned TCL_WIDE_INT_TYPE i); /* 69 */ EXTERN unsigned TCL_WIDE_INT_TYPE TclBN_mp_get_long_long(const mp_int *a); /* 70 */ EXTERN int TclBN_mp_set_long(mp_int *a, unsigned long i); /* 71 */ EXTERN unsigned long TclBN_mp_get_long(const mp_int *a); /* 72 */ EXTERN unsigned long TclBN_mp_get_int(const mp_int *a); /* 73 */ |
︙ | ︙ | |||
383 384 385 386 387 388 389 | int (*tclBN_mp_sub_d) (const mp_int *a, mp_digit b, mp_int *c); /* 43 */ int (*tclBN_mp_to_unsigned_bin) (const mp_int *a, unsigned char *b); /* 44 */ int (*tclBN_mp_to_unsigned_bin_n) (const mp_int *a, unsigned char *b, unsigned long *outlen); /* 45 */ int (*tclBN_mp_toradix_n) (const mp_int *a, char *str, int radix, int maxlen); /* 46 */ int (*tclBN_mp_unsigned_bin_size) (const mp_int *a); /* 47 */ int (*tclBN_mp_xor) (const mp_int *a, const mp_int *b, mp_int *c); /* 48 */ void (*tclBN_mp_zero) (mp_int *a); /* 49 */ | | | | | | | | | | | | | | | 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | int (*tclBN_mp_sub_d) (const mp_int *a, mp_digit b, mp_int *c); /* 43 */ int (*tclBN_mp_to_unsigned_bin) (const mp_int *a, unsigned char *b); /* 44 */ int (*tclBN_mp_to_unsigned_bin_n) (const mp_int *a, unsigned char *b, unsigned long *outlen); /* 45 */ int (*tclBN_mp_toradix_n) (const mp_int *a, char *str, int radix, int maxlen); /* 46 */ int (*tclBN_mp_unsigned_bin_size) (const mp_int *a); /* 47 */ int (*tclBN_mp_xor) (const mp_int *a, const mp_int *b, mp_int *c); /* 48 */ void (*tclBN_mp_zero) (mp_int *a); /* 49 */ void (*reserved50)(void); void (*reserved51)(void); void (*reserved52)(void); void (*reserved53)(void); void (*reserved54)(void); void (*reserved55)(void); void (*reserved56)(void); void (*reserved57)(void); void (*reserved58)(void); void (*reserved59)(void); void (*reserved60)(void); int (*tclBN_mp_init_set_int) (mp_int *a, unsigned long i); /* 61 */ int (*tclBN_mp_set_int) (mp_int *a, unsigned long i); /* 62 */ int (*tclBN_mp_cnt_lsb) (const mp_int *a); /* 63 */ void (*reserved64)(void); void (*reserved65)(void); void (*reserved66)(void); int (*tclBN_mp_expt_d_ex) (const mp_int *a, mp_digit b, mp_int *c, int fast); /* 67 */ int (*tclBN_mp_set_long_long) (mp_int *a, unsigned TCL_WIDE_INT_TYPE i); /* 68 */ unsigned TCL_WIDE_INT_TYPE (*tclBN_mp_get_long_long) (const mp_int *a); /* 69 */ int (*tclBN_mp_set_long) (mp_int *a, unsigned long i); /* 70 */ unsigned long (*tclBN_mp_get_long) (const mp_int *a); /* 71 */ unsigned long (*tclBN_mp_get_int) (const mp_int *a); /* 72 */ int (*tclBN_mp_tc_and) (const mp_int *a, const mp_int *b, mp_int *c); /* 73 */ int (*tclBN_mp_tc_or) (const mp_int *a, const mp_int *b, mp_int *c); /* 74 */ int (*tclBN_mp_tc_xor) (const mp_int *a, const mp_int *b, mp_int *c); /* 75 */ int (*tclBN_mp_tc_div_2d) (const mp_int *a, int b, mp_int *c); /* 76 */ |
︙ | ︙ | |||
524 525 526 527 528 529 530 | (tclTomMathStubsPtr->tclBN_mp_toradix_n) /* 46 */ #define TclBN_mp_unsigned_bin_size \ (tclTomMathStubsPtr->tclBN_mp_unsigned_bin_size) /* 47 */ #define TclBN_mp_xor \ (tclTomMathStubsPtr->tclBN_mp_xor) /* 48 */ #define TclBN_mp_zero \ (tclTomMathStubsPtr->tclBN_mp_zero) /* 49 */ | | | | | | | | | | | | < < < < < < < < < < < | 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 | (tclTomMathStubsPtr->tclBN_mp_toradix_n) /* 46 */ #define TclBN_mp_unsigned_bin_size \ (tclTomMathStubsPtr->tclBN_mp_unsigned_bin_size) /* 47 */ #define TclBN_mp_xor \ (tclTomMathStubsPtr->tclBN_mp_xor) /* 48 */ #define TclBN_mp_zero \ (tclTomMathStubsPtr->tclBN_mp_zero) /* 49 */ /* Slot 50 is reserved */ /* Slot 51 is reserved */ /* Slot 52 is reserved */ /* Slot 53 is reserved */ /* Slot 54 is reserved */ /* Slot 55 is reserved */ /* Slot 56 is reserved */ /* Slot 57 is reserved */ /* Slot 58 is reserved */ /* Slot 59 is reserved */ /* Slot 60 is reserved */ #define TclBN_mp_init_set_int \ (tclTomMathStubsPtr->tclBN_mp_init_set_int) /* 61 */ #define TclBN_mp_set_int \ (tclTomMathStubsPtr->tclBN_mp_set_int) /* 62 */ #define TclBN_mp_cnt_lsb \ (tclTomMathStubsPtr->tclBN_mp_cnt_lsb) /* 63 */ /* Slot 64 is reserved */ |
︙ | ︙ | |||
582 583 584 585 586 587 588 589 590 | #endif /* defined(USE_TCL_STUBS) */ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _TCLINTDECLS */ | > > > > > > > > > > > | 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 | #endif /* defined(USE_TCL_STUBS) */ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #undef TclBNInitBignumFromLong #define TclBNInitBignumFromLong(value) TclBNInitBignumFromWideInt((long) value) #ifdef USE_TCL_STUBS # undef TclBN_mp_set_long # ifdef TCL_WIDE_INT_IS_LONG # define TclBN_mp_set_long(a, b) TclBN_mp_set_long_long(a, (unsigned long)b) # else # define TclBN_mp_set_long(a, b) TclBN_mp_set_int(a, b) # endif #endif #endif /* _TCLINTDECLS */ |
Changes to generic/tclTomMathInterface.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | * Copyright (c) 2005 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | * Copyright (c) 2005 by Kevin B. Kenny. All rights reserved. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" #include "tommath_private.h" MODULE_SCOPE const TclTomMathStubs tclTomMathStubs; /* *---------------------------------------------------------------------- * * TclTommath_Init -- |
︙ | ︙ | |||
89 90 91 92 93 94 95 | { return TCLTOMMATH_REVISION; } /* *---------------------------------------------------------------------- * | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > > > > | | | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | { return TCLTOMMATH_REVISION; } /* *---------------------------------------------------------------------- * * TclInitBignumFromWideInt -- * * Allocate and initialize a 'bignum' from a Tcl_WideInt * * Results: * None. * * Side effects: * The 'bignum' is constructed. * *---------------------------------------------------------------------- */ #ifdef TCL_WIDE_INT_IS_LONG # define TclBN_mp_set_long_long TclBN_mp_set_long #endif void TclInitBignumFromWideInt( mp_int *a, /* Bignum to initialize */ Tcl_WideInt v) /* Initial value */ { if (mp_init_size(a, (CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT) != MP_OKAY) { Tcl_Panic("initialization failure in TclInitBignumFromWideInt"); } if (v < (Tcl_WideInt)0) { TclBN_mp_set_long_long(a, (Tcl_WideUInt)(-v)); mp_neg(a, a); } else { TclBN_mp_set_long_long(a, (Tcl_WideUInt)v); } } /* *---------------------------------------------------------------------- * * TclInitBignumFromWideUInt -- |
︙ | ︙ | |||
174 175 176 177 178 179 180 | TclInitBignumFromWideUInt( mp_int *a, /* Bignum to initialize */ Tcl_WideUInt v) /* Initial value */ { if (mp_init_size(a, (CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT) != MP_OKAY) { Tcl_Panic("initialization failure in TclInitBignumFromWideUInt"); } | | | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | TclInitBignumFromWideUInt( mp_int *a, /* Bignum to initialize */ Tcl_WideUInt v) /* Initial value */ { if (mp_init_size(a, (CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT) != MP_OKAY) { Tcl_Panic("initialization failure in TclInitBignumFromWideUInt"); } TclBN_mp_set_long_long(a, v); } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ |
Changes to libtommath/bn_fast_s_mp_sqr.c.
︙ | ︙ | |||
75 76 77 78 79 80 81 | /* even columns have the square term in them */ if (((unsigned)ix & 1u) == 0u) { _W += (mp_word)a->dp[ix>>1] * (mp_word)a->dp[ix>>1]; } /* store it */ | | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | /* even columns have the square term in them */ if (((unsigned)ix & 1u) == 0u) { _W += (mp_word)a->dp[ix>>1] * (mp_word)a->dp[ix>>1]; } /* store it */ W[ix] = (mp_digit)_W & MP_MASK; /* make next carry */ W1 = _W >> (mp_word)DIGIT_BIT; } /* setup dest */ olduse = b->used; |
︙ | ︙ |
Changes to libtommath/bn_mp_get_double.c.
︙ | ︙ | |||
15 16 17 18 19 20 21 | double mp_get_double(const mp_int *a) { int i; double d = 0.0, fac = 1.0; for (i = 0; i < DIGIT_BIT; ++i) { fac *= 2.0; } | | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | double mp_get_double(const mp_int *a) { int i; double d = 0.0, fac = 1.0; for (i = 0; i < DIGIT_BIT; ++i) { fac *= 2.0; } for (i = a->used; i --> 0;) { d = (d * fac) + (double)a->dp[i]; } return (mp_isneg(a) != MP_NO) ? -d : d; } #endif /* ref: $Format:%D$ */ /* git commit: $Format:%H$ */ |
︙ | ︙ |
Changes to libtommath/bn_mp_get_int.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | * * SPDX-License-Identifier: Unlicense */ /* get the lower 32-bits of an mp_int */ unsigned long mp_get_int(const mp_int *a) { | < < < < < < < < < < < < < < < < < | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | * * SPDX-License-Identifier: Unlicense */ /* get the lower 32-bits of an mp_int */ unsigned long mp_get_int(const mp_int *a) { /* force result to 32-bits always so it is consistent on non 32-bit platforms */ return mp_get_long(a) & 0xFFFFFFFFUL; } #endif /* ref: $Format:%D$ */ /* git commit: $Format:%H$ */ /* commit time: $Format:%ai$ */ |
Changes to libtommath/bn_mp_get_long.c.
︙ | ︙ | |||
22 23 24 25 26 27 28 | return 0; } /* get number of digits of the lsb we have to read */ i = MIN(a->used, ((((int)sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; /* get most significant digit of result */ | | | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | return 0; } /* get number of digits of the lsb we have to read */ i = MIN(a->used, ((((int)sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; /* get most significant digit of result */ res = (unsigned long)a->dp[i]; #if (ULONG_MAX != 0xFFFFFFFFUL) || (DIGIT_BIT < 32) while (--i >= 0) { res = (res << DIGIT_BIT) | (unsigned long)a->dp[i]; } #endif return res; } #endif /* ref: $Format:%D$ */ |
︙ | ︙ |
Changes to libtommath/bn_mp_get_long_long.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | * Michael Fromberger but has been written from scratch with * additional optimizations in place. * * SPDX-License-Identifier: Unlicense */ /* get the lower unsigned long long of an mp_int, platform dependent */ | | | | | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | * Michael Fromberger but has been written from scratch with * additional optimizations in place. * * SPDX-License-Identifier: Unlicense */ /* get the lower unsigned long long of an mp_int, platform dependent */ unsigned TCL_WIDE_INT_TYPE mp_get_long_long(const mp_int *a) { int i; unsigned TCL_WIDE_INT_TYPE res; if (a->used == 0) { return 0; } /* get number of digits of the lsb we have to read */ i = MIN(a->used, ((((int)sizeof(unsigned TCL_WIDE_INT_TYPE) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; /* get most significant digit of result */ res = (unsigned TCL_WIDE_INT_TYPE)a->dp[i]; #if DIGIT_BIT < 64 while (--i >= 0) { res = (res << DIGIT_BIT) | (unsigned TCL_WIDE_INT_TYPE)a->dp[i]; } #endif return res; } #endif /* ref: $Format:%D$ */ |
︙ | ︙ |
Changes to libtommath/bn_mp_is_square.c.
︙ | ︙ | |||
51 52 53 54 55 56 57 | /* digits used? (TSD) */ if (arg->used == 0) { return MP_OKAY; } /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ | | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | /* digits used? (TSD) */ if (arg->used == 0) { return MP_OKAY; } /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ if (rem_128[127u & arg->dp[0]] == (char)1) { return MP_OKAY; } /* Next check mod 105 (3*5*7) */ if ((res = mp_mod_d(arg, 105uL, &c)) != MP_OKAY) { return res; } |
︙ | ︙ |
Changes to libtommath/bn_mp_rand.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | /* First the OS-specific special cases * - *BSD * - Windows */ #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) #define MP_ARC4RANDOM | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* First the OS-specific special cases * - *BSD * - Windows */ #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) #define MP_ARC4RANDOM #define MP_GEN_RANDOM_MAX 0xFFFFFFFFU #define MP_GEN_RANDOM_SHIFT 32 static int s_read_arc4random(mp_digit *p) { mp_digit d = 0, msk = 0; do { d <<= MP_GEN_RANDOM_SHIFT; |
︙ | ︙ |
Changes to libtommath/bn_mp_set_double.c.
︙ | ︙ | |||
38 39 40 41 42 43 44 | res = (exp < 0) ? mp_div_2d(a, -exp, a, NULL) : mp_mul_2d(a, exp, a); if (res != MP_OKAY) { return res; } if (((cast.bits >> 63) != 0ULL) && (mp_iszero(a) == MP_NO)) { | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | res = (exp < 0) ? mp_div_2d(a, -exp, a, NULL) : mp_mul_2d(a, exp, a); if (res != MP_OKAY) { return res; } if (((cast.bits >> 63) != 0ULL) && (mp_iszero(a) == MP_NO)) { a->sign = MP_NEG; } return MP_OKAY; } #else /* pragma message() not supported by several compilers (in mostly older but still used versions) */ # ifdef _MSC_VER |
︙ | ︙ |
Changes to libtommath/bn_mp_set_int.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | * * SPDX-License-Identifier: Unlicense */ /* set a 32-bit const */ int mp_set_int(mp_int *a, unsigned long b) { | < < < < < < < < | < < < < < < < < < < < < < | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | * * SPDX-License-Identifier: Unlicense */ /* set a 32-bit const */ int mp_set_int(mp_int *a, unsigned long b) { return mp_set_long(a, b & 0xFFFFFFFFUL); } #endif /* ref: $Format:%D$ */ /* git commit: $Format:%H$ */ /* commit time: $Format:%ai$ */ |
Changes to libtommath/bn_mp_set_long_long.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | * Michael Fromberger but has been written from scratch with * additional optimizations in place. * * SPDX-License-Identifier: Unlicense */ /* set a platform dependent unsigned long long int */ | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 | * Michael Fromberger but has been written from scratch with * additional optimizations in place. * * SPDX-License-Identifier: Unlicense */ /* set a platform dependent unsigned long long int */ MP_SET_XLONG(mp_set_long_long, unsigned TCL_WIDE_INT_TYPE) #endif /* ref: $Format:%D$ */ /* git commit: $Format:%H$ */ /* commit time: $Format:%ai$ */ |
Changes to libtommath/tommath.h.
︙ | ︙ | |||
19 20 21 22 23 24 25 | #include "tommath_class.h" #ifdef __cplusplus extern "C" { #endif /* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */ | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include "tommath_class.h" #ifdef __cplusplus extern "C" { #endif /* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */ #if defined(_WIN32) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__) # define MP_32BIT #endif /* detect 64-bit mode if possible */ #if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || \ defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \ defined(__s390x__) || defined(__arch64__) || defined(__aarch64__) || \ |
︙ | ︙ | |||
41 42 43 44 45 46 47 | # else /* otherwise we fall back to MP_32BIT even on 64bit platforms */ # define MP_32BIT # endif # endif #endif | < < > > > > > > | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | # else /* otherwise we fall back to MP_32BIT even on 64bit platforms */ # define MP_32BIT # endif # endif #endif /* some default configurations. * * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits * * At the very least a mp_digit must be able to hold 7 bits * [any size beyond that is ok provided it doesn't overflow the data type] */ #ifdef MP_8BIT typedef unsigned char mp_digit; typedef unsigned short mp_word; # define MP_SIZEOF_MP_DIGIT 1 # ifdef DIGIT_BIT # error You must not define DIGIT_BIT when using MP_8BIT # endif #elif defined(MP_16BIT) typedef unsigned short mp_digit; typedef unsigned int mp_word; #endif # define MP_SIZEOF_MP_DIGIT 2 # ifdef DIGIT_BIT # error You must not define DIGIT_BIT when using MP_16BIT # endif #elif defined(MP_64BIT) /* for GCC only on supported platforms */ typedef unsigned long long mp_digit; typedef unsigned long mp_word __attribute__((mode(TI))); # define DIGIT_BIT 60 #else /* this is the default case, 28-bit digits */ /* this is to make porting into LibTomCrypt easier :-) */ typedef unsigned int mp_digit; #ifdef _WIN32 typedef unsigned __int64 mp_word; #else typedef unsigned long long mp_word; #endif #endif # ifdef MP_31BIT /* this is an extension that uses 31-bit digits */ # define DIGIT_BIT 31 # else /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ # define DIGIT_BIT 28 |
︙ | ︙ | |||
145 146 147 148 149 150 151 | # endif #endif /* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ #define MP_WARRAY (1u << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1)) /* the infamous mp_int structure */ | > > | > > | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | # endif #endif /* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ #define MP_WARRAY (1u << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1)) /* the infamous mp_int structure */ #ifndef MP_INT_DECLARED #define MP_INT_DECLARED typedef struct mp_int mp_int; #endif struct mp_int { int used, alloc, sign; mp_digit *dp; }; /* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */ typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); #define USED(m) ((m)->used) #define DIGIT(m, k) ((m)->dp[(k)]) |
︙ | ︙ | |||
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | /* set a 32-bit const */ int mp_set_int(mp_int *a, unsigned long b); /* set a platform dependent unsigned long value */ int mp_set_long(mp_int *a, unsigned long b); /* set a platform dependent unsigned long long value */ int mp_set_long_long(mp_int *a, unsigned long long b); /* get a double */ double mp_get_double(const mp_int *a); /* get a 32-bit value */ unsigned long mp_get_int(const mp_int *a); /* get a platform dependent unsigned long value */ unsigned long mp_get_long(const mp_int *a); /* get a platform dependent unsigned long long value */ unsigned long long mp_get_long_long(const mp_int *a); /* initialize and set a digit */ int mp_init_set(mp_int *a, mp_digit b); /* initialize and set 32-bit value */ int mp_init_set_int(mp_int *a, unsigned long b); | > > > > > > > > | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | /* set a 32-bit const */ int mp_set_int(mp_int *a, unsigned long b); /* set a platform dependent unsigned long value */ int mp_set_long(mp_int *a, unsigned long b); /* set a platform dependent unsigned long long value */ #ifdef _WIN32 int mp_set_long_long(mp_int *a, unsigned __int64 b); #else int mp_set_long_long(mp_int *a, unsigned long long b); #endif /* get a double */ double mp_get_double(const mp_int *a); /* get a 32-bit value */ unsigned long mp_get_int(const mp_int *a); /* get a platform dependent unsigned long value */ unsigned long mp_get_long(const mp_int *a); /* get a platform dependent unsigned long long value */ #ifdef _WIN32 unsigned __int64 mp_get_long_long(const mp_int *a); #else unsigned long long mp_get_long_long(const mp_int *a); #endif /* initialize and set a digit */ int mp_init_set(mp_int *a, mp_digit b); /* initialize and set 32-bit value */ int mp_init_set_int(mp_int *a, unsigned long b); |
︙ | ︙ |
Changes to libtommath/tommath_private.h.
︙ | ︙ | |||
81 82 83 84 85 86 87 | * x is the counter and unsigned * a is the pointer to the MPI * b is the original value that should be set in the MPI. */ #define MP_SET_XLONG(func_name, type) \ int func_name (mp_int * a, type b) \ { \ | | < < < < < | < | | > | < < < < < | < < | | | < | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | * x is the counter and unsigned * a is the pointer to the MPI * b is the original value that should be set in the MPI. */ #define MP_SET_XLONG(func_name, type) \ int func_name (mp_int * a, type b) \ { \ unsigned int x = 0; \ int res = mp_grow(a, (CHAR_BIT * sizeof(type) + DIGIT_BIT - 1) / DIGIT_BIT); \ if (res == MP_OKAY) { \ while (b) { \ a->dp[x++] = ((mp_digit)b & MP_MASK); \ b >>= DIGIT_BIT; \ } \ a->used = x; \ } \ return res; \ } #ifdef __cplusplus } #endif #endif |
︙ | ︙ |