diff options
| author | apnadkarni <apnmbx-wits@yahoo.com> | 2022-11-05 11:49:08 (GMT) |
|---|---|---|
| committer | apnadkarni <apnmbx-wits@yahoo.com> | 2022-11-05 11:49:08 (GMT) |
| commit | c3c5a80a02a02427696394cb0ed1f8adeab1099d (patch) | |
| tree | 2a821319db65ee920a8d0fb027a68ddcb51c903d | |
| parent | 6559f4084e844e187198c5471bfd15f19c8dfecc (diff) | |
| parent | d9033672db616bb406894a480e90410666ff4545 (diff) | |
| download | tcl-c3c5a80a02a02427696394cb0ed1f8adeab1099d.zip tcl-c3c5a80a02a02427696394cb0ed1f8adeab1099d.tar.gz tcl-c3c5a80a02a02427696394cb0ed1f8adeab1099d.tar.bz2 | |
Merge 8.7. lreplace4 bcc instruction and FLT_MAX fix
| -rw-r--r-- | generic/tclBasic.c | 4 | ||||
| -rw-r--r-- | generic/tclBinary.c | 4 | ||||
| -rw-r--r-- | generic/tclCompCmdsGR.c | 206 | ||||
| -rw-r--r-- | generic/tclCompile.c | 7 | ||||
| -rw-r--r-- | generic/tclCompile.h | 8 | ||||
| -rw-r--r-- | generic/tclExecute.c | 103 | ||||
| -rw-r--r-- | tests/binary.test | 81 |
7 files changed, 227 insertions, 186 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 5ab12d4..cd1bfc8 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -297,6 +297,7 @@ static const CmdInfo builtInCmds[] = { {"join", Tcl_JoinObjCmd, NULL, NULL, CMD_IS_SAFE}, {"lappend", Tcl_LappendObjCmd, TclCompileLappendCmd, NULL, CMD_IS_SAFE}, {"lassign", Tcl_LassignObjCmd, TclCompileLassignCmd, NULL, CMD_IS_SAFE}, + {"ledit", Tcl_LeditObjCmd, NULL, NULL, CMD_IS_SAFE}, {"lindex", Tcl_LindexObjCmd, TclCompileLindexCmd, NULL, CMD_IS_SAFE}, {"linsert", Tcl_LinsertObjCmd, TclCompileLinsertCmd, NULL, CMD_IS_SAFE}, {"list", Tcl_ListObjCmd, TclCompileListCmd, NULL, CMD_IS_SAFE|CMD_COMPILES_EXPANDED}, @@ -309,10 +310,9 @@ static const CmdInfo builtInCmds[] = { {"lreplace", Tcl_LreplaceObjCmd, TclCompileLreplaceCmd, NULL, CMD_IS_SAFE}, {"lreverse", Tcl_LreverseObjCmd, NULL, NULL, CMD_IS_SAFE}, {"lsearch", Tcl_LsearchObjCmd, NULL, NULL, CMD_IS_SAFE}, - {"lseq", Tcl_LseqObjCmd, NULL, NULL, CMD_IS_SAFE}, + {"lseq", Tcl_LseqObjCmd, NULL, NULL, CMD_IS_SAFE}, {"lset", Tcl_LsetObjCmd, TclCompileLsetCmd, NULL, CMD_IS_SAFE}, {"lsort", Tcl_LsortObjCmd, NULL, NULL, CMD_IS_SAFE}, - {"ledit", Tcl_LeditObjCmd, NULL, NULL, CMD_IS_SAFE}, {"package", Tcl_PackageObjCmd, NULL, TclNRPackageObjCmd, CMD_IS_SAFE}, {"proc", procObjCmd, NULL, NULL, CMD_IS_SAFE}, {"regexp", Tcl_RegexpObjCmd, TclCompileRegexpCmd, NULL, CMD_IS_SAFE}, diff --git a/generic/tclBinary.c b/generic/tclBinary.c index a7d6617..f27bb93 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -2051,7 +2051,11 @@ FormatNumber( */ if (fabs(dvalue) > (double) FLT_MAX) { + if (fabs(dvalue) > (FLT_MAX + pow(2, (FLT_MAX_EXP - FLT_MANT_DIG - 1)))) { + fvalue = (dvalue >= 0.0) ? INFINITY : -INFINITY; // c99 + } else { fvalue = (dvalue >= 0.0) ? FLT_MAX : -FLT_MAX; + } } else { fvalue = (float) dvalue; } diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 2ea3b77..efa36ad 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1356,84 +1356,34 @@ TclCompileLinsertCmd( CompileEnv *envPtr) /* Holds the resulting instructions. */ { DefineLineInformation; /* TIP #280 */ - Tcl_Token *tokenPtr, *listTokenPtr; - int idx, i; + Tcl_Token *tokenPtr; + int i; if ((int)parsePtr->numWords < 3) { return TCL_ERROR; } - listTokenPtr = TokenAfter(parsePtr->tokenPtr); - - /* - * Parse the index. Will only compile if it is constant and not an - * _integer_ less than zero (since we reserve negative indices here for - * end-relative indexing) or an end-based index greater than 'end' itself. - */ - - tokenPtr = TokenAfter(listTokenPtr); - - /* - * NOTE: This command treats all inserts at indices before the list - * the same as inserts at the start of the list, and all inserts - * after the list the same as inserts at the end of the list. We - * make that transformation here so we can use the optimized bytecode - * as much as possible. - */ - if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_END, - &idx) != TCL_OK) { - return TCL_ERROR; - } - - /* - * There are four main cases. If there are no values to insert, this is - * just a confirm-listiness check. If the index is '0', this is a prepend. - * If the index is 'end' (== TCL_INDEX_END), this is an append. Otherwise, - * this is a splice (== split, insert values as list, concat-3). - */ - - CompileWord(envPtr, listTokenPtr, interp, 1); - if (parsePtr->numWords == 3) { - TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); - TclEmitInt4( (int)TCL_INDEX_END, envPtr); - return TCL_OK; - } + + /* Push list, insertion index onto the stack */ + tokenPtr = TokenAfter(parsePtr->tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 1); + tokenPtr = TokenAfter(tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 2); + /* Push new elements to be inserted */ for (i=3 ; i<(int)parsePtr->numWords ; i++) { tokenPtr = TokenAfter(tokenPtr); CompileWord(envPtr, tokenPtr, interp, i); } - TclEmitInstInt4( INST_LIST, i - 3, envPtr); - if (idx == (int)TCL_INDEX_START) { - TclEmitInstInt4( INST_REVERSE, 2, envPtr); - TclEmitOpcode( INST_LIST_CONCAT, envPtr); - } else if (idx == (int)TCL_INDEX_END) { - TclEmitOpcode( INST_LIST_CONCAT, envPtr); - } else { - /* - * Here we handle two ranges for idx. First when idx > 0, we - * want the first half of the split to end at index idx-1 and - * the second half to start at index idx. - * Second when idx < TCL_INDEX_END, indicating "end-N" indexing, - * we want the first half of the split to end at index end-N and - * the second half to start at index end-N+1. We accomplish this - * with a pre-adjustment of the end-N value. - * The root of this is that the commands [lrange] and [linsert] - * differ in their interpretation of the "end" index. - */ - - if (idx < (int)TCL_INDEX_END) { - idx++; - } - TclEmitInstInt4( INST_OVER, 1, envPtr); - TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); - TclEmitInt4( idx - 1, envPtr); - TclEmitInstInt4( INST_REVERSE, 3, envPtr); - TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr); - TclEmitInt4( (int)TCL_INDEX_END, envPtr); - TclEmitOpcode( INST_LIST_CONCAT, envPtr); - TclEmitOpcode( INST_LIST_CONCAT, envPtr); - } + /* First operand is count of arguments */ + TclEmitInstInt4(INST_LREPLACE4, parsePtr->numWords - 1, envPtr); + /* + * Second operand is bitmask + * TCL_LREPLACE4_END_IS_LAST - end refers to last element + * TCL_LREPLACE4_SINGLE_INDEX - second index is not present + * indicating this is a pure insert + */ + TclEmitInt1(TCL_LREPLACE4_SINGLE_INDEX, envPtr); return TCL_OK; } @@ -1458,116 +1408,34 @@ TclCompileLreplaceCmd( CompileEnv *envPtr) /* Holds the resulting instructions. */ { DefineLineInformation; /* TIP #280 */ - Tcl_Token *tokenPtr, *listTokenPtr; - int idx1, idx2, i; - int emptyPrefix=1, suffixStart = 0; - - if ((int)parsePtr->numWords < 4) { - return TCL_ERROR; - } - listTokenPtr = TokenAfter(parsePtr->tokenPtr); + Tcl_Token *tokenPtr; + int i; - tokenPtr = TokenAfter(listTokenPtr); - if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_NONE, - &idx1) != TCL_OK) { + if (parsePtr->numWords < 4) { return TCL_ERROR; } + /* Push list, first, last onto the stack */ + tokenPtr = TokenAfter(parsePtr->tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 1); tokenPtr = TokenAfter(tokenPtr); - if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_NONE, TCL_INDEX_END, - &idx2) != TCL_OK) { - return TCL_ERROR; - } - - /* - * General structure of the [lreplace] result is - * prefix replacement suffix - * In a few cases we can predict various parts will be empty and - * take advantage. - * - * The proper suffix begins with the greater of indices idx1 or - * idx2 + 1. If we cannot tell at compile time which is greater, - * we must defer to direct evaluation. - */ - - if (idx1 == (int)TCL_INDEX_NONE) { - suffixStart = (int)TCL_INDEX_NONE; - } else if (idx2 == (int)TCL_INDEX_NONE) { - suffixStart = idx1; - } else if (idx2 == (int)TCL_INDEX_END) { - suffixStart = (int)TCL_INDEX_NONE; - } else if (((idx2 < (int)TCL_INDEX_END) && (idx1 <= (int)TCL_INDEX_END)) - || ((idx2 >= (int)TCL_INDEX_START) && (idx1 >= (int)TCL_INDEX_START))) { - suffixStart = (idx1 > idx2 + 1) ? idx1 : idx2 + 1; - } else { - return TCL_ERROR; - } - - /* All paths start with computing/pushing the original value. */ - CompileWord(envPtr, listTokenPtr, interp, 1); + CompileWord(envPtr, tokenPtr, interp, 2); + tokenPtr = TokenAfter(tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 3); - /* - * Push all the replacement values next so any errors raised in - * creating them get raised first. - */ - if ((int)parsePtr->numWords > 4) { - /* Push the replacement arguments */ + /* Push new elements to be inserted */ + for (i=4 ; i< (int) parsePtr->numWords ; i++) { tokenPtr = TokenAfter(tokenPtr); - for (i=4 ; i<(int)parsePtr->numWords ; i++) { - CompileWord(envPtr, tokenPtr, interp, i); - tokenPtr = TokenAfter(tokenPtr); - } - - /* Make a list of them... */ - TclEmitInstInt4( INST_LIST, i - 4, envPtr); - - emptyPrefix = 0; - } - - if ((idx1 == suffixStart) && (parsePtr->numWords == 4)) { - /* - * This is a "no-op". Example: [lreplace {a b c} 2 0] - * We still do a list operation to get list-verification - * and canonicalization side effects. - */ - TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); - TclEmitInt4( (int)TCL_INDEX_END, envPtr); - return TCL_OK; - } - - if (idx1 != (int)TCL_INDEX_START) { - /* Prefix may not be empty; generate bytecode to push it */ - if (emptyPrefix) { - TclEmitOpcode( INST_DUP, envPtr); - } else { - TclEmitInstInt4( INST_OVER, 1, envPtr); - } - TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); - TclEmitInt4( idx1 - 1, envPtr); - if (!emptyPrefix) { - TclEmitInstInt4( INST_REVERSE, 2, envPtr); - TclEmitOpcode( INST_LIST_CONCAT, envPtr); - } - emptyPrefix = 0; - } - - if (!emptyPrefix) { - TclEmitInstInt4( INST_REVERSE, 2, envPtr); + CompileWord(envPtr, tokenPtr, interp, i); } - if (suffixStart == (int)TCL_INDEX_NONE) { - TclEmitOpcode( INST_POP, envPtr); - if (emptyPrefix) { - PushStringLiteral(envPtr, ""); - } - } else { - /* Suffix may not be empty; generate bytecode to push it */ - TclEmitInstInt4( INST_LIST_RANGE_IMM, suffixStart, envPtr); - TclEmitInt4( (int)TCL_INDEX_END, envPtr); - if (!emptyPrefix) { - TclEmitOpcode( INST_LIST_CONCAT, envPtr); - } - } + /* First operand is count of arguments */ + TclEmitInstInt4(INST_LREPLACE4, parsePtr->numWords - 1, envPtr); + /* + * Second operand is bitmask + * TCL_LREPLACE4_END_IS_LAST - end refers to last element + */ + TclEmitInt1(TCL_LREPLACE4_END_IS_LAST, envPtr); return TCL_OK; } diff --git a/generic/tclCompile.c b/generic/tclCompile.c index a57743c..b38a657 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -657,6 +657,13 @@ InstructionDesc const tclInstructionTable[] = { /* String Less or equal: push (stknext <= stktop) */ {"strge", 1, -1, 0, {OPERAND_NONE}}, /* String Greater or equal: push (stknext >= stktop) */ + {"lreplace4", 6, INT_MIN, 2, {OPERAND_UINT4, OPERAND_UINT1}}, + /* Operands: number of arguments, flags + * flags: Combination of TCL_LREPLACE4_* flags + * Stack: ... listobj index1 ?index2? new1 ... newN => ... newlistobj + * where index2 is present only if TCL_LREPLACE_SINGLE_INDEX is not + * set in flags. + */ {NULL, 0, 0, 0, {OPERAND_NONE}} }; diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 30b1819..035edac 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -835,6 +835,8 @@ enum TclInstruction { INST_STR_LE, INST_STR_GE, + INST_LREPLACE4, + /* The last opcode */ LAST_INST_OPCODE }; @@ -1673,6 +1675,12 @@ MODULE_SCOPE int TclPushProcCallFrame(void *clientData, #define TCL_NO_ELEMENT 2 /* Do not push the array element. */ /* + * Flags bits used by lreplace4 instruction + */ +#define TCL_LREPLACE4_END_IS_LAST 1 /* "end" refers to last element */ +#define TCL_LREPLACE4_SINGLE_INDEX 2 /* Second index absent (pure insert) */ + +/* * DTrace probe macros (NOPs if DTrace support is not enabled). */ diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 444f9aa..e2a2705 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5034,11 +5034,104 @@ TEBCresume( NEXT_INST_F(1, 1, 0); } - /* - * End of INST_LIST and related instructions. - * ----------------------------------------------------------------- - * Start of string-related instructions. - */ + case INST_LREPLACE4: + { + Tcl_Size numToDelete, numNewElems; + int end_indicator; + int haveSecondIndex, flags; + Tcl_Obj *fromIdxObj, *toIdxObj; + opnd = TclGetInt4AtPtr(pc + 1); + flags = TclGetInt1AtPtr(pc + 5); + + /* Stack: ... listobj index1 ?index2? new1 ... newN */ + valuePtr = OBJ_AT_DEPTH(opnd-1); + + /* haveSecondIndex==0 => pure insert */ + haveSecondIndex = (flags & TCL_LREPLACE4_SINGLE_INDEX) == 0; + numNewElems = opnd - 2 - haveSecondIndex; + + /* end_indicator==1 => "end" is last element's index, 0=>index beyond */ + end_indicator = (flags & TCL_LREPLACE4_END_IS_LAST) != 0; + fromIdxObj = OBJ_AT_DEPTH(opnd - 2); + toIdxObj = haveSecondIndex ? OBJ_AT_DEPTH(opnd - 3) : NULL; + if (Tcl_ListObjLength(interp, valuePtr, &length) != TCL_OK) { + TRACE_ERROR(interp); + goto gotError; + } + + DECACHE_STACK_INFO(); + + if (TclGetIntForIndexM( + interp, fromIdxObj, length - end_indicator, &fromIdx) + != TCL_OK) { + CACHE_STACK_INFO(); + TRACE_ERROR(interp); + goto gotError; + } + if (fromIdx == TCL_INDEX_NONE) { + fromIdx = 0; + } + else if (fromIdx > length) { + fromIdx = length; + } + numToDelete = 0; + if (toIdxObj) { + if (TclGetIntForIndexM( + interp, toIdxObj, length - end_indicator, &toIdx) + != TCL_OK) { + CACHE_STACK_INFO(); + TRACE_ERROR(interp); + goto gotError; + } + if (toIdx != TCL_INDEX_NONE) { + if (toIdx > length) { + toIdx = length; + } + if (toIdx >= fromIdx) { + numToDelete = toIdx - fromIdx + 1; + } + } + } + + CACHE_STACK_INFO(); + + if (Tcl_IsShared(valuePtr)) { + objResultPtr = Tcl_DuplicateObj(valuePtr); + if (Tcl_ListObjReplace(interp, + objResultPtr, + fromIdx, + numToDelete, + numNewElems, + &OBJ_AT_DEPTH(numNewElems - 1)) + != TCL_OK) { + TRACE_ERROR(interp); + Tcl_DecrRefCount(objResultPtr); + goto gotError; + } + TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr))); + NEXT_INST_V(6, opnd, 1); + } + else { + if (Tcl_ListObjReplace(interp, + valuePtr, + fromIdx, + numToDelete, + numNewElems, + &OBJ_AT_DEPTH(numNewElems - 1)) + != TCL_OK) { + TRACE_ERROR(interp); + goto gotError; + } + TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr))); + NEXT_INST_V(6, opnd - 1, 0); + } + } + + /* + * End of INST_LIST and related instructions. + * ----------------------------------------------------------------- + * Start of string-related instructions. + */ case INST_STR_EQ: case INST_STR_NEQ: /* String (in)equality check */ diff --git a/tests/binary.test b/tests/binary.test index 1d0e36d..a947410 100644 --- a/tests/binary.test +++ b/tests/binary.test @@ -512,10 +512,10 @@ test binary-13.11 {Tcl_BinaryObjCmd: format} littleEndian { } \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 test binary-13.12 {Tcl_BinaryObjCmd: float overflow} bigEndian { binary format f -3.402825e+38 -} \xFF\x7F\xFF\xFF +} \xFF\x80\x00\x00 test binary-13.13 {Tcl_BinaryObjCmd: float overflow} littleEndian { binary format f -3.402825e+38 -} \xFF\xFF\x7F\xFF +} \x00\x00\x80\xFF test binary-13.14 {Tcl_BinaryObjCmd: float underflow} bigEndian { binary format f -3.402825e-100 } \x80\x00\x00\x00 @@ -537,6 +537,18 @@ test binary-13.19 {Tcl_BinaryObjCmd: format} littleEndian { set a {1.6 3.4} binary format f1 $a } \xCD\xCC\xCC\x3F +test binary-13.20 {Tcl_BinaryObjCmd: format float Inf} bigEndian { + binary format f Inf +} \x7F\x80\x00\x00 +test binary-13.21 {Tcl_BinaryObjCmd: format float Inf} littleEndian { + binary format f Inf +} \x00\x00\x80\x7F +test binary-13.22 {Tcl_BinaryObjCmd: format float -Inf} bigEndian { + binary format f -Inf +} \xFF\x80\x00\x00 +test binary-13.23 {Tcl_BinaryObjCmd: format float -Inf} littleEndian { + binary format f -Inf +} \x00\x00\x80\xFF test binary-14.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body { binary format d @@ -1975,10 +1987,10 @@ test binary-53.11 {Tcl_BinaryObjCmd: format} {} { } \xCD\xCC\xCC\x3F\x9A\x99\x59\x40 test binary-53.12 {Tcl_BinaryObjCmd: float overflow} {} { binary format R -3.402825e+38 -} \xFF\x7F\xFF\xFF +} \xFF\x80\x00\x00 test binary-53.13 {Tcl_BinaryObjCmd: float overflow} {} { binary format r -3.402825e+38 -} \xFF\xFF\x7F\xFF +} \x00\x00\x80\xFF test binary-53.14 {Tcl_BinaryObjCmd: float underflow} {} { binary format R -3.402825e-100 } \x80\x00\x00\x00 @@ -2000,6 +2012,39 @@ test binary-53.19 {Tcl_BinaryObjCmd: format} {} { set a {1.6 3.4} binary format r1 $a } \xCD\xCC\xCC\x3F +test binary-53.20 {Tcl_BinaryObjCmd: float Inf} {} { + binary format R Inf +} \x7f\x80\x00\x00 +test binary-53.21 {Tcl_BinaryObjCmd: float Inf} {} { + binary format r Inf +} \x00\x00\x80\x7f +test binary-53.22 {Binary float Inf round trip} -body { + binary scan [binary format R Inf] R inf + binary scan [binary format R -Inf] R inf_ + list $inf $inf_ +} -result {Inf -Inf} +test binary-53.23 {Binary float round to FLT_MAX} -body { + binary scan [binary format H* 7f7fffff] R fltmax + binary scan [binary format H* 47effffff0000000] Q round_to_fltmax + binary scan [binary format R $round_to_fltmax] R fltmax1 + expr {$fltmax eq $fltmax1} +} -result 1 +test binary-53.24 {Binary float round to -FLT_MAX} -body { + binary scan [binary format H* ff7fffff] R fltmax + binary scan [binary format H* c7effffff0000000] Q round_to_fltmax + binary scan [binary format R $round_to_fltmax] R fltmax1 + expr {$fltmax eq $fltmax1} +} -result 1 +test binary-53.25 {Binary float round to Inf} -body { + binary scan [binary format H* 47effffff0000001] Q round_to_inf + binary scan [binary format R $round_to_inf] R inf1 + expr {$inf1 eq Inf} +} -result 1 +test binary-53.26 {Binary float round to -Inf} -body { + binary scan [binary format H* c7effffff0000001] Q round_to_inf + binary scan [binary format R $round_to_inf] R inf1 + expr {$inf1 eq -Inf} +} -result 1 # scan t (s) test binary-54.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body { @@ -2396,11 +2441,27 @@ test binary-62.4 {infinity} ieeeFloatingPoint { format 0x%016lx $w } 0xfff0000000000000 test binary-62.5 {infinity} ieeeFloatingPoint { - binary scan [binary format w 0x7ff0000000000000] q d + binary scan [binary format w 0x7FF0000000000000] q d set d } Inf test binary-62.6 {infinity} ieeeFloatingPoint { - binary scan [binary format w 0xfff0000000000000] q d + binary scan [binary format w 0xFFF0000000000000] q d + set d +} -Inf +test binary-62.7 {infinity} ieeeFloatingPoint { + binary scan [binary format r Inf] iu i + format 0x%08x $i +} 0x7f800000 +test binary-62.8 {infinity} ieeeFloatingPoint { + binary scan [binary format r -Inf] iu i + format 0x%08x $i +} 0xff800000 +test binary-62.9 {infinity} ieeeFloatingPoint { + binary scan [binary format i 0x7F800000] r d + set d +} Inf +test binary-62.10 {infinity} ieeeFloatingPoint { + binary scan [binary format i 0xFF800000] r d set d } -Inf @@ -2408,19 +2469,19 @@ test binary-62.6 {infinity} ieeeFloatingPoint { test binary-63.1 {NaN} ieeeFloatingPoint { binary scan [binary format q NaN] w w - format 0x%016lx [expr {$w & 0xfff3ffffffffffff}] + format 0x%016lx [expr {$w & 0xFFF3FFFFFFFFFFFF}] } 0x7ff0000000000000 test binary-63.2 {NaN} ieeeFloatingPoint { binary scan [binary format q -NaN] w w - format 0x%016lx [expr {$w & 0xfff3ffffffffffff}] + format 0x%016lx [expr {$w & 0xFFF3FFFFFFFFFFFF}] } 0xfff0000000000000 test binary-63.3 {NaN} ieeeFloatingPoint { binary scan [binary format q NaN(3123456789aBc)] w w - format 0x%016lx [expr {$w & 0xfff3ffffffffffff}] + format 0x%016lx [expr {$w & 0xFFF3FFFFFFFFFFFF}] } 0x7ff3123456789abc test binary-63.4 {NaN} ieeeFloatingPoint { binary scan [binary format q {NaN( 3123456789aBc)}] w w - format 0x%016lx [expr {$w & 0xfff3ffffffffffff}] + format 0x%016lx [expr {$w & 0xFFF3FFFFFFFFFFFF}] } 0x7ff3123456789abc # Make sure TclParseNumber() rejects invalid nan-hex formats [Bug 3402540] |
