diff --git a/CHANGES b/CHANGES index 722f7a4..4d8c7a2 100644 --- a/CHANGES +++ b/CHANGES @@ -23,6 +23,27 @@ The following are the changes from calc version 2.14.2.0 to date: we removed the setjmp() call. Thanks to for raising this potential concern. + Added config("tilde_space", boolean). The "tilde_space" controls + whether or not a space (' ') is printed after leading tilde ('~'). + By default, config("tilde_space") is true, which is a change + from past behavior. For example, now: + + ; 1/3 + ~ 0.33333333333333333333 + + With config("tilde_space", 0): + + ; 1/3 + ~0.33333333333333333333 + + To disable "tilde_space", use config("tilde_space", 0) on the + command line and/or use config("tilde_space", 0),; in your ~/.calcrc. + Thanks goes to for this suggestion. + + Added config("tilde_space", boolean) to help/config, along with + a few few minor text improvements. Updated cal/regress to test + config("tilde_space") and to account for the new default. + The following are the changes from calc version 2.14.1.2 to date: diff --git a/cal/regress.cal b/cal/regress.cal index c083e0c..212b9d0 100644 --- a/cal/regress.cal +++ b/cal/regress.cal @@ -2033,8 +2033,8 @@ define test_mode() '1685: str(0xffffffff) == \"4.294967295e9\"'); vrfy(str(3e9) == "3e9", \ '1686: str(3e9) == \"3e9\"'); - vrfy(str(1/3) == "~3.33333333333333333333e-1", \ - '1687: str(1/3) == \"~3.33333333333333333333e-1\"'); + vrfy(str(1/3) == "~ 3.33333333333333333333e-1", \ + '1687: str(1/3) == \"~ 3.33333333333333333333e-1\"'); vrfy(str(2e8) == "2e8", \ '1688: str(2e8) == \"2e8"'); vrfy(str(200e6) == "2e8", \ @@ -2054,8 +2054,8 @@ define test_mode() '1695: str(0xffffffff) == \"4.294967295e9\"'); vrfy(str(3e9) == "3e9", \ '1696: str(3e9) == \"3e9\"'); - vrfy(str(1/3) == "~333.33333333333333333333e-3", \ - '1697: str(1/3) == \"~333.33333333333333333333e-3\"'); + vrfy(str(1/3) == "~ 333.33333333333333333333e-3", \ + '1697: str(1/3) == \"~ 333.33333333333333333333e-3\"'); vrfy(str(2e8) == "200e6", \ '1698: str(2e8) == \"200e6"'); vrfy(str(200e6) == "200e6", \ @@ -2075,8 +2075,8 @@ define test_mode() '1705: str(0xffffffff) == \"4294967295\"'); vrfy(str(3e9) == "3000000000", \ '1706: str(3e9) == \"3000000000\"'); - vrfy(str(1/3) == "~0", \ - '1707: str(1/3) == \"~0\"'); + vrfy(str(1/3) == "~ 0", \ + '1707: str(1/3) == \"~ 0\"'); vrfy(str(2e8) == "200000000", \ '1708: str(2e8) == \"200000000"'); vrfy(str(200e6) == "200000000", \ @@ -2096,8 +2096,8 @@ define test_mode() '1715: str(0xffffffff) == \"4294967295\"'); vrfy(str(3e9) == "3000000000", \ '1716: str(3e9) == \"3000000000\"'); - vrfy(str(1/3) == "~0.33333333333333333333", \ - '1717: str(1/3) == \"~0.33333333333333333333"'); + vrfy(str(1/3) == "~ 0.33333333333333333333", \ + '1717: str(1/3) == \"~ 0.33333333333333333333"'); vrfy(str(2e8) == "200000000", \ '1718: str(2e8) == \"200000000"'); vrfy(str(200e6) == "200000000", \ @@ -2151,8 +2151,8 @@ define test_mode() vrfy(base2() == -10, '1745: base2() == -10'); vrfy(str(23209) == "23209 /* 23209 */", '1746: str(23209) == "23209 /* 23209 */"'); - vrfy(str(3/2) == "1.5 /* ~2 */", - '1747: str(3/2) == "1.5 /* ~2 */"'); + vrfy(str(3/2) == "1.5 /* ~ 2 */", + '1747: str(3/2) == "1.5 /* ~ 2 */"'); vrfy(base2(1000) == -10, '1748: base2(1000) == -1000'); vrfy(base2() == 1000, '1749: base2() == 1000'); @@ -4296,84 +4296,114 @@ define test_strprintf() print '4804: c = config("display", 2)'; c = config("tilde", 0); print '4805: c = config("tilde", 0)'; + c = config("tilde_space", 1); + print '4806: c = config("tilde_space", 1)'; c = config("leadzero", 0); - print '4806: c = config("leadzero", 0)'; + print '4807: c = config("leadzero", 0)'; c = config("fullzero", 0); - print '4807: c = config("fullzero", 0)'; + print '4808: c = config("fullzero", 0)'; /* tests with tilde == 0 */ vrfy(strprintf("%d%d", 27, 29) == "2729", - '4808: strprintf("%d%d", 27, 29) == "2729"'); + '4809: strprintf("%d%d", 27, 29) == "2729"'); vrfy(strprintf("%5d%3d", 27, 29) == " 27 29", - '4809: strprintf("%5d%3d", 27, 29) == " 27 29"; '); + '4810: strprintf("%5d%3d", 27, 29) == " 27 29"; '); vrfy(strprintf("%-5d%-3d", 27, 29) == "27 29 ", - '4810: strprintf("%-5d%-3d", 27, 29) == "27 29 "'); + '4811: strprintf("%-5d%-3d", 27, 29) == "27 29 "'); vrfy(strprintf("%f", 1.375) == "1.38", - '4811: strprintf("%f", 1.375) == "1.38"'); + '4812: strprintf("%f", 1.375) == "1.38"'); vrfy(strprintf("%f", 1.385) == "1.38", - '4812: strprintf("%f", 1.385) == "1.38"'); + '4813: strprintf("%f", 1.385) == "1.38"'); vrfy(strprintf("%f", .375) == ".38", - '4813: strprintf("%f", .375) == ".38"'); + '4814: strprintf("%f", .375) == ".38"'); vrfy(strprintf("%f", .385) == ".38", - '4814: strprintf("%f", .385) == ".38"'); + '4815: strprintf("%f", .385) == ".38"'); /* tests with tilde == 1 */ c = config("tilde", 1); - print '4815: c = config("tilde", 1)'; - vrfy(strprintf("%f", 1.375) == "~1.38", - '4816: strprintf("%f", 1.375) == "~1.38"'); - vrfy(strprintf("%f", 27/29) == "~.93", - '4817: strprintf("%f", 27/29) == "~.93"'); + print '4816: c = config("tilde", 1)'; + vrfy(strprintf("%f", 1.375) == "~ 1.38", + '4817: strprintf("%f", 1.375) == "~ 1.38"'); + vrfy(strprintf("%f", 27/29) == "~ .93", + '4818: strprintf("%f", 27/29) == "~ .93"'); vrfy(strprintf("%r", 27/29) == "27/29", - '4818: strprintf("%r", 27/29) == "27/29"'); + '4819: strprintf("%r", 27/29) == "27/29"'); vrfy(strprintf("%o", 27/29) == "033/035", - '4819: strprintf("%o", 27/29) == "033/035"'); + '4820: strprintf("%o", 27/29) == "033/035"'); vrfy(strprintf("%x", 27/29) == "0x1b/0x1d", - '4820: strprintf("%x", 27/29) == "0x1b/0x1d"'); + '4821: strprintf("%x", 27/29) == "0x1b/0x1d"'); vrfy(strprintf("%b", 27/29) == "0b11011/0b11101", - '4821: strprintf("%b", 27/29) == "0b11011/0b11101"'); + '4822: strprintf("%b", 27/29) == "0b11011/0b11101"'); + vrfy(strprintf("%e", 12345) == "~ 1.23e4", + '4823: strprintf("%e", 12345) == "~ 1.23e4"'); + vrfy(strprintf("%g", .385) == "~ .38", + '4824: strprintf("%g", .385) == "~ .38"'); + vrfy(strprintf("%g", 385) == "~ 3.8e2", + '4825: strprintf("%g", 385) == "~ 3.8e2"'); + + /* tests with tilde == 1 and tilde_space == 0 */ + c = config("tilde_space", 0); + print '4826: c = config("tilde_space", 0)'; + vrfy(strprintf("%f", 1.375) == "~1.38", + '4827: strprintf("%f", 1.375) == "~1.38"'); + vrfy(strprintf("%f", 27/29) == "~.93", + '4828: strprintf("%f", 27/29) == "~.93"'); vrfy(strprintf("%e", 12345) == "~1.23e4", - '4822: strprintf("%e", 12345) == "~1.23e4"'); + '4829: strprintf("%e", 12345) == "~1.23e4"'); vrfy(strprintf("%g", .385) == "~.38", - '4823: strprintf("%g", .385) == "~.38"'); + '4830: strprintf("%g", .385) == "~.38"'); vrfy(strprintf("%g", 385) == "~3.8e2", - '4824: strprintf("%g", 385) == "~3.8e2"'); + '4831: strprintf("%g", 385) == "~3.8e2"'); + + /* tests with tilde_space == 0 */ + c = config("tilde_space", 1); + print '4832: c = config("tilde_space", 1)'; + vrfy(strprintf("%f", 1.375) == "~ 1.38", + '4833: strprintf("%f", 1.375) == "~ 1.38"'); + vrfy(strprintf("%f", 27/29) == "~ .93", + '4834: strprintf("%f", 27/29) == "~ .93"'); + vrfy(strprintf("%e", 12345) == "~ 1.23e4", + '4835: strprintf("%e", 12345) == "~ 1.23e4"'); + vrfy(strprintf("%g", .385) == "~ .38", + '4836: strprintf("%g", .385) == "~ .38"'); + vrfy(strprintf("%g", 385) == "~ 3.8e2", + '4837: strprintf("%g", 385) == "~ 3.8e2"'); /* mode tests with tilde == 0 */ c = config("tilde", 0); - print '4825: c = config("tilde", 0)'; + print '4838: c = config("tilde", 0)'; vrfy(strprintf("%e", 12345) == "1.23e4", - '4826: strprintf("%e", 12345) == "1.23e4"'); + '4839: strprintf("%e", 12345) == "1.23e4"'); vrfy(strprintf("%.3e", 12345) == "1.234e4", - '4827: strprintf("%.3e", 12345) == "1.234e4"'); + '4840: strprintf("%.3e", 12345) == "1.234e4"'); vrfy(strprintf("%e", .00012345) == "1.23e-4", - '4828: strprintf("%e", .00012345) == "1.23e-4"'); + '4841: strprintf("%e", .00012345) == "1.23e-4"'); vrfy(strprintf("%d %d", 27) == "27 ", - '4829: strprintf("%d %d", 27) == "27 "'); + '4842: strprintf("%d %d", 27) == "27 "'); vrfy(strprintf("%d", 27, 29) == "27", - '4830: strprintf("%d", 27, 29) == "27"'); + '4843: strprintf("%d", 27, 29) == "27"'); vrfy(strprintf("%r = %f", 27/29, 27/29) == "27/29 = .93", - '4831: strprintf("%r = %f", 27/29, 27/29) == "27/29 = .93"'); + '4844: strprintf("%r = %f", 27/29, 27/29) == "27/29 = .93"'); vrfy(strprintf("%s", "abc") == "abc", - '4832: strprintf("%s", "abc") == "abc"'); + '4845: strprintf("%s", "abc") == "abc"'); vrfy(strprintf("%f", "abc") == "abc", - '4833: strprintf("%f", "abc") == "abc"'); + '4846: strprintf("%f", "abc") == "abc"'); vrfy(strprintf("%e", "abc") == "abc", - '4834: strprintf("%e", "abc") == "abc"'); + '4847: strprintf("%e", "abc") == "abc"'); vrfy(strprintf("%5s", "abc") == " abc", - '4835: strprintf("%5s", "abc") == " abc"'); + '4848: strprintf("%5s", "abc") == " abc"'); vrfy(strprintf("%-5s", "abc") == "abc ", - '4836: strprintf("%-5s", "abc") == "abc "'); + '4849: strprintf("%-5s", "abc") == "abc "'); vrfy(strprintf("%g", .385) == ".38", - '4837: strprintf("%g", .385) == ".38"'); + '4850: strprintf("%g", .385) == ".38"'); vrfy(strprintf("%g", 385) == "3.8e2", - '4838: strprintf("%g", 385) == "3.8e2"'); + '4851: strprintf("%g", 385) == "3.8e2"'); /* restore config */ c = config("all", callcfg); - print '4839: c = config("all", callcfg)'; + print '4852: c = config("all", callcfg)'; - print '4840: Ending test_strprintf'; + print '4853: Ending test_strprintf'; } print '088: parsed test_fileop()'; diff --git a/config.c b/config.c index 6d0a1bc..01e93d3 100644 --- a/config.c +++ b/config.c @@ -93,6 +93,7 @@ NAMETYPE configs[] = { {"pow2", CONFIG_POW2}, {"redc2", CONFIG_REDC2}, {"tilde", CONFIG_TILDE}, + {"tilde_space", CONFIG_TILDE_SPACE}, {"tab", CONFIG_TAB}, {"quomod", CONFIG_QUOMOD}, {"quo", CONFIG_QUO}, @@ -151,6 +152,7 @@ CONFIG oldstd = { /* backward compatible standard configuration */ POW_ALG2, /* size of modulus to use REDC for powers */ REDC_ALG2, /* size of modulus to use REDC algorithm 2 */ TRUE, /* OK to print a tilde on approximations */ + FALSE, /* OK to print a space after tilde on approximations */ TRUE, /* OK to print tab before numeric values */ 0, /* quomod() default rounding mode */ 2, /* quotient // default rounding mode */ @@ -211,6 +213,7 @@ CONFIG newstd = { /* new non-backward compatible configuration */ POW_ALG2, /* size of modulus to use REDC for powers */ REDC_ALG2, /* size of modulus to use REDC algorithm 2 */ TRUE, /* OK to print a tilde on approximations */ + TRUE, /* OK to print a space after tilde on approximations */ TRUE, /* OK to print tab before numeric values */ 0, /* quomod() default rounding mode */ 2, /* quotient // default rounding mode */ @@ -624,6 +627,20 @@ setconfig(int type, VALUE *vp) } break; + case CONFIG_TILDE_SPACE: + if (vp->v_type == V_NUM) { + q = vp->v_num; + conf->tilde_space = !qiszero(q); + } else if (vp->v_type == V_STR) { + temp = lookup_long(truth, vp->v_str->s_str); + if (temp < 0) { + math_error("Illegal truth value for tilde_space"); + not_reached(); + } + conf->tilde_space = (int)temp; + } + break; + case CONFIG_TAB: if (vp->v_type == V_NUM) { q = vp->v_num; @@ -1205,6 +1222,10 @@ config_value(CONFIG *cfg, int type, VALUE *vp) i = (cfg->tilde_ok ? 1 : 0); break; + case CONFIG_TILDE_SPACE: + i = (cfg->tilde_space ? 1 : 0); + break; + case CONFIG_TAB: i = (cfg->tab_ok ? 1 : 0); break; diff --git a/config.h b/config.h index 85a0ca4..3e8b050 100644 --- a/config.h +++ b/config.h @@ -94,6 +94,7 @@ #define CONFIG_REDECL_WARN 44 #define CONFIG_DUPVAR_WARN 45 #define CONFIG_HZ 46 +#define CONFIG_TILDE_SPACE 47 /* @@ -131,6 +132,7 @@ struct config { LEN pow2; /* size of modulus to use REDC for powers */ LEN redc2; /* size of modulus to use REDC algorithm 2 */ BOOL tilde_ok; /* OK to print a tilde on approximations */ + BOOL tilde_space; /* print space after tilde on approximations */ BOOL tab_ok; /* OK to print tab before numeric values */ LEN quomod; /* quomod() default rounding mode */ LEN quo; /* quotient // default rounding mode */ diff --git a/hash.c b/hash.c index 2b80142..ce35c88 100644 --- a/hash.c +++ b/hash.c @@ -956,6 +956,7 @@ hash_value(int type, void *v, HASH *state) state = hash_len(type, value->v_config->pow2, state); state = hash_len(type, value->v_config->redc2, state); state = hash_bool(type, value->v_config->tilde_ok, state); + state = hash_bool(type, value->v_config->tilde_space, state); state = hash_bool(type, value->v_config->tab_ok, state); state = hash_long(type, (long)value->v_config->quomod, state); state = hash_long(type, (long)value->v_config->quo, state); diff --git a/help/config b/help/config index bbb14a8..a1d069e 100644 --- a/help/config +++ b/help/config @@ -34,6 +34,7 @@ DESCRIPTION "pow2" sets size for alternate powering. "redc2" sets size for alternate REDC. "tilde" enable/disable printing of the roundoff '~' + "tilde_space" enable/disable printing space after roundoff tilde '~ ' "tab" enable/disable printing of leading tabs "quomod" sets rounding mode for quomod "quo" sets rounding mode for //, default for quo @@ -134,6 +135,7 @@ DESCRIPTION config("display", 50); 50 digits of output epsilon(epsilon() / 8); 3 bits more accuracy config("tilde", 0) disable roundoff tilde printing + config("tilde_space", 0) disable printing space after roundoff tilde config("tab", "off") disable leading tab printing =-= @@ -264,7 +266,7 @@ DESCRIPTION config("mul2", int) config("sq2", int) - Mul2 and sq2 specify the sizes of numbers at which calc switches + Both "mul2" and "sq2" specify the sizes of numbers at which calc switches from its first to its second algorithm for multiplying and squaring. The first algorithm is the usual method of cross multiplying, which runs in a time of O(N^2). The second method is a recursive and @@ -305,7 +307,7 @@ DESCRIPTION config("pow2", int) - Pow2 specifies the sizes of numbers at which calc switches from + The "pow2" specifies the sizes of numbers at which calc switches from its first to its second algorithm for calculating powers modulo another number. The first algorithm for calculating modular powers is by repeated squaring and multiplying and dividing by the modulus. @@ -334,7 +336,7 @@ DESCRIPTION config("redc2", int) - Redc2 specifies the sizes of numbers at which calc switches from + The "redc2" specifies the sizes of numbers at which calc switches from its first to its second algorithm when using the REDC algorithm. The first algorithm performs a multiply and a modular reduction together in one loop which runs in O(N^2). The second algorithm @@ -363,16 +365,30 @@ DESCRIPTION config("tilde", boolean) - Config("tilde") controls whether or not a leading tilde ('~') is + The "tilde" controls whether or not a leading tilde ('~') is printed to indicate that a number has not been printed exactly because the number of decimal digits required would exceed the - specified maximum number. The initial "tilde" value is 1. + specified maximum number. + + If config("tilde") is false, then config("tilde_space") has no effect. + + The initial "tilde" value is 1. + + =-= + + config("tilde_space", boolean) + + The "tilde_space" controls whether or not a space (' ') is + printed after leading tilde ('~'). See config("tilde") above. + If config("tilde") is false, then config("tilde_space") has no effect. + + The initial "tilde_space" value is 1. =-= config("tab", boolean) - Config ("tab") controls the printing of a tab before results + config("tab") controls the printing of a tab before results automatically displayed when working interactively. It does not affect the printing by the functions print, printf, etc. The initial "tab" value is 1. diff --git a/lib_calc.c b/lib_calc.c index 2af283c..32ef0bb 100644 --- a/lib_calc.c +++ b/lib_calc.c @@ -321,6 +321,7 @@ libcalc_call_me_first(void) if (d_flag) { conf->resource_debug = 0; conf->tilde_ok = 0; + conf->tilde_space = 0; } /* diff --git a/qio.c b/qio.c index 131ad82..fb41d31 100644 --- a/qio.c +++ b/qio.c @@ -201,16 +201,24 @@ qprintnum(NUMBER *q, int outmode, LEN outdigits) } switch (outmode) { case MODE_INT: - if (conf->tilde_ok && qisfrac(q)) + if (conf->tilde_ok && qisfrac(q)) { PUTCHAR('~'); + if (conf->tilde_space && qisfrac(q)) { + PUTCHAR(' '); + } + } qprintfd(q, 0L); break; case MODE_REAL: prec = qdecplaces(q); if ((prec < 0) || (prec > outdigits)) { - if (conf->tilde_ok) + if (conf->tilde_ok) { PUTCHAR('~'); + if (conf->tilde_space) { + PUTCHAR(' '); + } + } } if (conf->fullzero || (prec < 0) || (prec > outdigits)) diff --git a/quickhash.c b/quickhash.c index 9a584d1..3d28bd5 100644 --- a/quickhash.c +++ b/quickhash.c @@ -439,6 +439,7 @@ config_hash(CONFIG *cfg, QCKHASH val) value = (((value>>5) | (value<<27)) ^ (USB32)cfg->pow2); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->redc2); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->tilde_ok); + value = (((value>>5) | (value<<27)) ^ (USB32)cfg->tilde_space); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->tab_ok); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->quomod); value = (((value>>5) | (value<<27)) ^ (USB32)cfg->quo);