Mercurial > hg > xemacs-beta
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) |