comparison src/print.c @ 577:910449c92002

[xemacs-hg @ 2001-05-25 10:04:26 by hrvojen] Commit the new, faster version of long_to_string. Published in <sxsofsiy5ze.fsf@florida.arsdigita.de>.
author hrvojen
date Fri, 25 May 2001 10:04:29 +0000
parents 4326eeed6933
children 0e1f61d4b978
comparison
equal deleted inserted replaced
576:6db80f4ab17c 577:910449c92002
938 buf [(buf [0] == '-' ? 1 : 0)] = '0'; 938 buf [(buf [0] == '-' ? 1 : 0)] = '0';
939 } 939 }
940 } 940 }
941 #endif /* LISP_FLOAT_TYPE */ 941 #endif /* LISP_FLOAT_TYPE */
942 942
943 /* Print NUMBER to BUFFER. 943 #define ONE_DIGIT(figure) *p++ = n / (figure) + '0'
944 This is equivalent to sprintf (buffer, "%ld", number), only much faster. 944 #define ONE_DIGIT_ADVANCE(figure) (ONE_DIGIT (figure), n %= (figure))
945 945
946 BUFFER should accept 24 bytes. This should suffice for the longest 946 #define DIGITS_1(figure) ONE_DIGIT (figure)
947 numbers on 64-bit machines, including the `-' sign and the trailing 947 #define DIGITS_2(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_1 ((figure) / 10)
948 '\0'. Returns a pointer to the trailing '\0'. */ 948 #define DIGITS_3(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_2 ((figure) / 10)
949 char * 949 #define DIGITS_4(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_3 ((figure) / 10)
950 #define DIGITS_5(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_4 ((figure) / 10)
951 #define DIGITS_6(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_5 ((figure) / 10)
952 #define DIGITS_7(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_6 ((figure) / 10)
953 #define DIGITS_8(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_7 ((figure) / 10)
954 #define DIGITS_9(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_8 ((figure) / 10)
955 #define DIGITS_10(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_9 ((figure) / 10)
956
957 /* DIGITS_<11-20> are only used on machines with 64-bit longs. */
958
959 #define DIGITS_11(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_10 ((figure) / 10)
960 #define DIGITS_12(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_11 ((figure) / 10)
961 #define DIGITS_13(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_12 ((figure) / 10)
962 #define DIGITS_14(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_13 ((figure) / 10)
963 #define DIGITS_15(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_14 ((figure) / 10)
964 #define DIGITS_16(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_15 ((figure) / 10)
965 #define DIGITS_17(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_16 ((figure) / 10)
966 #define DIGITS_18(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_17 ((figure) / 10)
967 #define DIGITS_19(figure) ONE_DIGIT_ADVANCE (figure); DIGITS_18 ((figure) / 10)
968
969 /* Print NUMBER to BUFFER in base 10. This is completely equivalent
970 to `sprintf(buffer, "%ld", number)', only much faster.
971
972 The speedup may make a difference in programs that frequently
973 convert numbers to strings. Some implementations of sprintf,
974 particularly the one in GNU libc, have been known to be extremely
975 slow compared to this function.
976
977 BUFFER should accept as many bytes as you expect the number to take
978 up. On machines with 64-bit longs the maximum needed size is 24
979 bytes. That includes the worst-case digits, the optional `-' sign,
980 and the trailing \0. */
981
982 void
950 long_to_string (char *buffer, long number) 983 long_to_string (char *buffer, long number)
951 { 984 {
985 char *p = buffer;
986 long n = number;
987
952 #if (SIZEOF_LONG != 4) && (SIZEOF_LONG != 8) 988 #if (SIZEOF_LONG != 4) && (SIZEOF_LONG != 8)
953 /* Huh? */ 989 /* We are running in a strange or misconfigured environment. Let
954 sprintf (buffer, "%ld", number); 990 sprintf cope with it. */
955 return buffer + strlen (buffer); 991 sprintf (buffer, "%ld", n);
956 #else /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */ 992 #else /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */
957 char *p = buffer; 993
958 int force = 0; 994 if (n < 0)
959
960 if (number < 0)
961 { 995 {
962 *p++ = '-'; 996 *p++ = '-';
963 number = -number; 997 n = -n;
964 } 998 }
965 999
966 #define FROB(figure) do { \ 1000 if (n < 10) { DIGITS_1 (1); }
967 if (force || number >= figure) \ 1001 else if (n < 100) { DIGITS_2 (10); }
968 *p++ = number / figure + '0', number %= figure, force = 1; \ 1002 else if (n < 1000) { DIGITS_3 (100); }
969 } while (0) 1003 else if (n < 10000) { DIGITS_4 (1000); }
970 #if SIZEOF_LONG == 8 1004 else if (n < 100000) { DIGITS_5 (10000); }
971 FROB (1000000000000000000L); 1005 else if (n < 1000000) { DIGITS_6 (100000); }
972 FROB (100000000000000000L); 1006 else if (n < 10000000) { DIGITS_7 (1000000); }
973 FROB (10000000000000000L); 1007 else if (n < 100000000) { DIGITS_8 (10000000); }
974 FROB (1000000000000000L); 1008 else if (n < 1000000000) { DIGITS_9 (100000000); }
975 FROB (100000000000000L); 1009 #if SIZEOF_LONG == 4
976 FROB (10000000000000L); 1010 /* ``if (1)'' serves only to preserve editor indentation. */
977 FROB (1000000000000L); 1011 else if (1) { DIGITS_10 (1000000000); }
978 FROB (100000000000L); 1012 #else /* SIZEOF_LONG != 4 */
979 FROB (10000000000L); 1013 else if (n < 10000000000L) { DIGITS_10 (1000000000L); }
980 #endif /* SIZEOF_LONG == 8 */ 1014 else if (n < 100000000000L) { DIGITS_11 (10000000000L); }
981 FROB (1000000000); 1015 else if (n < 1000000000000L) { DIGITS_12 (100000000000L); }
982 FROB (100000000); 1016 else if (n < 10000000000000L) { DIGITS_13 (1000000000000L); }
983 FROB (10000000); 1017 else if (n < 100000000000000L) { DIGITS_14 (10000000000000L); }
984 FROB (1000000); 1018 else if (n < 1000000000000000L) { DIGITS_15 (100000000000000L); }
985 FROB (100000); 1019 else if (n < 10000000000000000L) { DIGITS_16 (1000000000000000L); }
986 FROB (10000); 1020 else if (n < 100000000000000000L) { DIGITS_17 (10000000000000000L); }
987 FROB (1000); 1021 else if (n < 1000000000000000000L) { DIGITS_18 (100000000000000000L); }
988 FROB (100); 1022 else { DIGITS_19 (1000000000000000000L); }
989 FROB (10); 1023 #endif /* SIZEOF_LONG != 4 */
990 #undef FROB 1024
991 *p++ = number + '0';
992 *p = '\0'; 1025 *p = '\0';
993 return p;
994 #endif /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */ 1026 #endif /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */
995 } 1027 }
1028
1029 #undef ONE_DIGIT
1030 #undef ONE_DIGIT_ADVANCE
1031
1032 #undef DIGITS_1
1033 #undef DIGITS_2
1034 #undef DIGITS_3
1035 #undef DIGITS_4
1036 #undef DIGITS_5
1037 #undef DIGITS_6
1038 #undef DIGITS_7
1039 #undef DIGITS_8
1040 #undef DIGITS_9
1041 #undef DIGITS_10
1042 #undef DIGITS_11
1043 #undef DIGITS_12
1044 #undef DIGITS_13
1045 #undef DIGITS_14
1046 #undef DIGITS_15
1047 #undef DIGITS_16
1048 #undef DIGITS_17
1049 #undef DIGITS_18
1050 #undef DIGITS_19
996 1051
997 static void 1052 static void
998 print_vector_internal (const char *start, const char *end, 1053 print_vector_internal (const char *start, const char *end,
999 Lisp_Object obj, 1054 Lisp_Object obj,
1000 Lisp_Object printcharfun, int escapeflag) 1055 Lisp_Object printcharfun, int escapeflag)