static value_t fl_truncate(value_t *args, u_int32_t nargs) { argcount("truncate", nargs, 1); if (isfixnum(args[0])) return args[0]; if (iscprim(args[0])) { cprim_t *cp = (cprim_t*)ptr(args[0]); void *data = cp_data(cp); numerictype_t nt = cp_numtype(cp); double d; if (nt == T_FLOAT) d = (double)*(float*)data; else if (nt == T_DOUBLE) d = *(double*)data; else return args[0]; if (d > 0) { if (d > (double)U64_MAX) return args[0]; return return_from_uint64((uint64_t)d); } if (d > (double)S64_MAX || d < (double)S64_MIN) return args[0]; return return_from_int64((int64_t)d); } type_error("truncate", "number", args[0]); }
int isnumtok_base(char *tok, value_t *pval, int base) { char *end; int64_t i64; uint64_t ui64; double d; if (*tok == '\0') return 0; if (!((tok[0]=='0' && tok[1]=='x') || (base >= 15)) && strpbrk(tok, ".eEpP")) { d = strtod(tok, &end); if (*end == '\0') { if (pval) *pval = mk_double(d); return 1; } // floats can end in f or f0 if (end > tok && end[0] == 'f' && (end[1] == '\0' || (end[1] == '0' && end[2] == '\0'))) { if (pval) *pval = mk_float((float)d); return 1; } } if (tok[0] == '+') { if (!strcmp(tok,"+NaN") || !strcasecmp(tok,"+nan.0")) { if (pval) *pval = mk_double(D_PNAN); return 1; } if (!strcmp(tok,"+Inf") || !strcasecmp(tok,"+inf.0")) { if (pval) *pval = mk_double(D_PINF); return 1; } } else if (tok[0] == '-') { if (!strcmp(tok,"-NaN") || !strcasecmp(tok,"-nan.0")) { if (pval) *pval = mk_double(D_NNAN); return 1; } if (!strcmp(tok,"-Inf") || !strcasecmp(tok,"-inf.0")) { if (pval) *pval = mk_double(D_NINF); return 1; } errno = 0; i64 = strtoll(tok, &end, base); if (errno) return 0; if (pval) *pval = return_from_int64(i64); return (*end == '\0'); } errno = 0; ui64 = strtoull_0b0o(tok, &end, base); if (errno) return 0; if (pval) *pval = return_from_uint64(ui64); return (*end == '\0'); }