home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / DRI-archive / roche / BYTESTAT.TXT < prev    next >
Internet Message Format  |  2009-12-11  |  25KB

  1. From: "Salle Arobase" <salle.arob...@ville-rochefort.fr>
  2. Newsgroups: comp.os.cpm
  3. Subject: Re: French Luser news
  4. Date: Tue, 19 Aug 2003 16:08:08 +0200
  5. Organization: Ville de Rochefort
  6. Lines: 580
  7. Message-ID: <bhtagr$s89$1@news-reader4.wanadoo.fr>
  8. References: <be3ocf$k4v$1@news-reader1.wanadoo.fr> <bf4dtp$sg8$1@news.hobby.nl> <1058421800snz@nospam.demon.co.uk> <bfbfjm$7kq$1@news-reader1.wanadoo.fr> <1058725031snz@nospam.demon.co.uk> <bfj8n6$3ar$1@news-reader4.wanadoo.fr> <1058904250snz@nospam.demon.co.uk> <bfr17q$jml$1@news-reader5.wanadoo.fr>
  9. Reply-To: "Salle Arobase" <salle.arob...@ville-rochefort.fr>
  10. NNTP-Posting-Host: apoitiers-106-2-3-98.w81-248.abo.wanadoo.fr
  11. X-Trace: news-reader4.wanadoo.fr 1061301595 28937 81.248.43.98 (19 Aug 2003 13:59:55 GMT)
  12. X-Complaints-To: abuse@wanadoo.fr
  13. NNTP-Posting-Date: 19 Aug 2003 13:59:55 GMT
  14. X-Priority: 3
  15. X-MSMail-Priority: Normal
  16. X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
  17. X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
  18.  
  19. BYTESTAT.TXT  by Emmanuel ROCHE
  20. ------------
  21.  
  22. A solution in search of a problem...
  23.  
  24. Since last time, I have been  busy working  on the  WS4 to  HTML
  25. converter. I had a lot to learn about the internals  of WS4  and
  26. HTML. Since the main  problem was  how to  display properly  WS4
  27. tables, I was surprised to see  how difficult  it is  with HTML.
  28. There are hundreds of Web pages dealing with this subject alone.
  29.  
  30. It  seems  that the  origin of  this difficulty  is the  lack of
  31. backward compatibility. Instead of starting from  an ASR-33  TTY
  32. with its 72 columns of (monospaced) characters, "the powers that
  33. are on the Internet" started with the number of pixels displayed
  34. on the screen.  So,  when you  want to  display something  under
  35. HTML, you are obliged to say how many pixels to use...
  36.  
  37. Of course, since most stuff does not fit on a single "page", you
  38. need to add "elevators" on the right side,  and a  border around
  39. your text, all taking some more  pixels from  the screen.   As a
  40. result, most text I  have read  so far  counsel to  assume that,
  41. instead of 640 pixels wide, the lowest resolution  for a  screen
  42. should be 600 pixels...
  43.  
  44. Well, this will make for interesting  stuff when  CP/M computers
  45. will have a Browser, since most of them had not 640 pixels. Back
  46. then, in the prehistoric dark ages, we used to think in  term of
  47. the number of characters  displayed... and  most CP/M  computers
  48. used to be able to display  80 characters  (for example,  to use
  49. WordStar), but rarely had 640 pixels (use CP/M on an  Apple IIe,
  50. and you will understand).
  51.  
  52. One day  that I  was thinking  about this  strange asking  of 64
  53. columns only (even in the 21th Century), it came to  me that  we
  54. usually think  in decimal.   And we  often use  percentages, and
  55. values less  than 100.   For instance,  in France  phone numbers
  56. have 10 numbers, which are written as 01.23.45.67.89 (this could
  57. be a  valid phone  number). You  never pronounce  the "hundred".
  58. Only values less than  100, which  are more  often used.   So, I
  59. asked myself: "Would it be possible to display  100 things  on a
  60. 64 columns line?"
  61.  
  62. I noticed that 64 is slightly  more than  50. The  problem being
  63. that, to display 100 things on  50 columns,  you would  need one
  64. character  displaying  2 symbols...   that already  exist (as  a
  65. character) but one with only one  representation...  Now,  it so
  66. happens that, in French, semicolon is  "deux points"  (two dots)
  67. and, of course, period  is "point  (final)" ((ending)  dot). So,
  68. here I had my 2 characters, one displaying one symbol, the other
  69. displaying two times the same symbol.
  70.  
  71. (As you  can see,  I think  a lot,  and sometimes  (most of  the
  72. times?) to  things that  are "obvious"  to anybody  else. Me,  I
  73. spend my time asking: "Why... this  or that?"   I seem  to never
  74. have grown up.)
  75.  
  76. I jumped to my computer, and  produced the  following histogram,
  77. which should be self-explanatory:
  78.  
  79. run"percent
  80.   0|
  81.   1|.
  82.   2|:
  83.   3|:.
  84.   4|::
  85.   5|::.
  86.   6|:::
  87.   7|:::.
  88.   8|::::
  89.   9|::::.
  90.  10|:::::
  91. Break in 50
  92. Ok
  93.  
  94. So, we are now able to display percentages on a 64-columns line.
  95. The program which produced the above follows:
  96.  
  97. list
  98. 10 REM PERCENT.BAS  by Emmanuel ROCHE
  99. 20 :
  100. 30 FOR i = 0 TO 100
  101. 40     GOSUB 90
  102. 50     IF i MOD 21 = 20 THEN WHILE INKEY$ = "" : WEND
  103. 60 NEXT i
  104. 70 END
  105. 80 :
  106. 90 ' Percent
  107. 100 PRINT USING "###" ; i ;
  108. 110 PRINT "|" ;
  109. 120 ' 0 = even
  110. 130 ' 1 = odd
  111. 140 IF i MOD 2 = 0 THEN PRINT STRING$ (i/2, ":") ELSE PRINT
  112. STRING$ ((i-1)/2, ":") "."
  113. 150 RETURN
  114.  
  115. Now,  it  so  happens  that, while  working on  the WS4  to HTML
  116. converter,  I  was  wondering  which  were  the more  often used
  117. characters in a file? Difficult question,  since characters  are
  118. coded using bytes with 256 values, and most  files usually  hold
  119. thousands of characters... Counting them by hand would  be quite
  120. a chore!
  121.  
  122. Now, it so happens  that, recently,  I wrote  a "general-purpose
  123. filter program in BASIC". Instead of acting upon  the occurrence
  124. of each of the 256 possible values of a byte, a simple variation
  125. of this program, counting the number of times a  particular byte
  126. value was found inside a file, would solve this problem...
  127.  
  128. But, there are still some problems on the way. How do you  prove
  129. that such a program works accurately?  Everything in  a computer
  130. (including files and bytes)  are powers  of 2,  and we  think in
  131. decimal (and want the results displayed in percentages!)
  132.  
  133. The only solution was to create some test  files. I  re-used the
  134. MAKEASCF.BAS program that was mentioned in the FILTER.TXT  file.
  135. To be sure that the file really contains the wanted  values, the
  136. only solution is to inspect it with a DUMP program.
  137.  
  138. Ok
  139. dir *.bin
  140.  ASCII   .BIN  ZEROES  .BIN  ZEREOF  .BIN  SUITEA  .BIN
  141.  
  142. Ok
  143. run"dumpfile
  144.  
  145. DUMPFILE: Enter filename.ext: ? ascii.bin
  146.  
  147. 0000: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ................
  148. 0010: 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F ................
  149. 0020: 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F  !"#$%&'()*+,-./
  150. 0030: 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 0123456789:;<=>?
  151. 0040: 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F @ABCDEFGHIJKLMNO
  152. 0050: 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F PQRSTUVWXYZ[\]^_
  153. 0060: 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F `abcdefghijklmno
  154. 0070: 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F pqrstuvwxyz{|}~.
  155. 0080: 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F ................
  156. 0090: 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F ................
  157. 00A0: A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF ................
  158. 00B0: B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF ................
  159. 00C0: C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF ................
  160. 00D0: D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF ................
  161. 00E0: E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF ................
  162. 00F0: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF ................
  163.  
  164. Ok
  165.  
  166. I know what will complain those people (probably  using a  2-GHz
  167. computers) asking that I use 64 columns:  the above  dump is  71
  168. columns wide...  Well, would it not be time enough to upgrade to
  169. an ASR-33 TTY, you guys?  At least, you could print those  dumps
  170. on  a  30-years  old  Teletype. What  use is  Windows and  2-GHz
  171. computers, if they are not able to display 80 columns of text on
  172. 17" screens?
  173.  
  174. So,  this  was  the  usual  256  values  of  a  byte,  with  its
  175. corresponding  USASCII  characters.  Now,  let us  see what  our
  176. program diplaying the percentages of usage of byte  values in  a
  177. file produces:
  178.  
  179. run"bytestat
  180.  
  181. BYTESTAT: Enter filename.typ : ? ascii.bin
  182.  
  183. Percentages of bytes usage inside file ASCII.BIN.
  184.  
  185. % | .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F
  186. --+------------------------------------------------
  187. 0.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  188. 1.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  189. 2.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  190. 3.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  191. 4.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  192. 5.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  193. 6.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  194. 7.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  195. 8.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  196. 9.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  197. A.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  198. B.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  199. C.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  200. D.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  201. E.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  202. F.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  203.  
  204. Do you want a histogram? (y/N) n
  205.  
  206. Ok
  207.  
  208. Big surprise! We have just seen that there is one  occurrence of
  209. each byte value in the file, yet the program says that each  one
  210. occurs "zero percent"! The reason is  that we  think in  decimal
  211. (or  hundred),  and the  file holds  256 bytes  holding the  256
  212. possible values of a byte. And, 1/256=0.003 percent.   Since the
  213. program only display percentages (it is assuming that  no single
  214. value will occur 100% of the time in all the  bytes, so  it only
  215. uses  2  digits to  display the  percentages) and  the value  is
  216. 0.003, it only displays a "00" (which is automatically  shrinked
  217. down to "0").
  218.  
  219. Well... This seems a reasonable explanation.  Could we  test the
  220. case that must never occurs, when  all the  bytes have  the same
  221. values? Sure, we modify the line of MAKEASCF so that, instead of
  222. writing the value of the loop index into the file,  it writes  a
  223. 00h byte  256 times.  One more  DUMP to  be sure  that the  file
  224. really contains them. See below.
  225.  
  226. Just one remark about the use of "0." and ".0".  This goes  back
  227. to the ANSI text (1967?) defining the ASCII character set.   For
  228. some  unknow  reasons,  it  was displayed  vertically.  I  had a
  229. slight problem (at the  beginning, since  I started  programming
  230. using  EBCDIC  on  IBM  Mainframes.  I  was a  COBOL programmer)
  231. understanding what were the axes of the ASCII table. Since  then
  232. (many, many years ago...), I have  used this  way of  indicating
  233. which are the "high order axis" and the  "low order  axis". This
  234. works nicely  when displaying  only 2-digits  max values.   When
  235. displaying only single digit values (or characters), I hope that
  236. the  reader  will  understand  that  the  table  is   positioned
  237. horizontally.
  238.  
  239. (The carriage of the printwheel of my TTY runs horizontally, not
  240. vertically. ASCII was standardised based on the TTY, which was a
  241. best-seller, the standard I/O device for more than 20 years.   A
  242. whole generation learned to use computers using one. Screens (or
  243. "glass TTYs") were quite a revolution when they were introduced.
  244. In fact, the first CP/M system had no screen (hence the names of
  245. the "virtual devices" of CP/M 2.2: CON, PUN, RDR, LST,  and NUL,
  246. which was a wheel inside the  TTY generating  a standard  answer
  247. message of 40 characters  (a string  of 00h  if not  set), as  I
  248. explained several times.))
  249.  
  250. run"dumpfile
  251.  
  252. DUMPFILE: Enter filename.ext: ? zeroes.bin
  253.  
  254. 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  255. 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  256. 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  257. 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  258. 0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  259. 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  260. 0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  261. 0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  262. 0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  263. 0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  264. 00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  265. 00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  266. 00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  267. 00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  268. 00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  269. 00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  270.  
  271. Ok
  272. run"bytestat
  273.  
  274. BYTESTAT: Enter filename.typ : ? zeroes.bin
  275.  
  276. Percentages of bytes usage inside file ZEROES.BIN.
  277.  
  278. % | .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F
  279. --+------------------------------------------------
  280. 0.| %100  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  281. 1.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  282. 2.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  283. 3.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  284. 4.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  285. 5.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  286. 6.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  287. 7.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  288. 8.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  289. 9.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  290. A.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  291. B.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  292. C.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  293. D.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  294. E.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  295. F.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  296.  
  297. Do you want a histogram? (y/N) y
  298.  
  299. 00|::::::::::::::::::::::::::::::::::::::::::::::::::
  300.  
  301. Ok
  302.  
  303. The program  worked correctly.   It is  not designed  to display
  304. values appearing more than 99%, so  an overflow  occurred, which
  305. produced  the  "%100" displayed  above. All  the other  256 byte
  306. values are not used, so count  for "zero  percent". Finally,  we
  307. takes  this  opportunity to  test the  output of  the histogram.
  308. When  we  move  the  cursor at  the end  of the  line, the  word
  309. processor   indicates   "Column   54".   Since   there   are  50
  310. "semicolons", the 2-digits hex value at left and  a border  (and
  311. the cursor), we are  correct in  getting 54  columns. (We  could
  312. even  have  preceded  the  histogram  with  a  space  or  a  tab
  313. (8+54=63)...)
  314.  
  315. Now, let us see what happens when testing the contents of a file
  316. filled with only 2 values: 00h and 1Ah (zero and eof):
  317.  
  318. run"dumpfile
  319.  
  320. DUMPFILE: Enter filename.ext: ? zereof.bin
  321.  
  322. 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  323. 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  324. 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  325. 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  326. 0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  327. 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  328. 0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  329. 0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  330. 0080: 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................
  331. 0090: 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................
  332. 00A0: 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................
  333. 00B0: 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................
  334. 00C0: 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................
  335. 00D0: 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................
  336. 00E0: 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................
  337. 00F0: 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A ................
  338.  
  339. Ok
  340. run"bytestat
  341.  
  342. BYTESTAT: Enter filename.typ : ? zereof.bin
  343.  
  344. Percentages of bytes usage inside file ZEREOF.BIN.
  345.  
  346. % | .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F
  347. --+------------------------------------------------
  348. 0.| 50  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  349. 1.|  0  0  0  0  0  0  0  0  0  0 50  0  0  0  0  0
  350. 2.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  351. 3.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  352. 4.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  353. 5.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  354. 6.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  355. 7.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  356. 8.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  357. 9.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  358. A.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  359. B.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  360. C.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  361. D.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  362. E.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  363. F.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  364.  
  365. Do you want a histogram? (y/N) y
  366.  
  367. 00|:::::::::::::::::::::::::
  368. 1A|:::::::::::::::::::::::::
  369.  
  370. Ok
  371.  
  372. It works. 00h is used 50% of the time. 1Ah  is used  50% of  the
  373. time. The remaining 254 values are used 0% of the time.
  374.  
  375. Let us finish with a more difficult case. We start  with a  line
  376. of zeroes, then one "1", then two "2", then three "3", etc.  See
  377. the following DUMP to see the internals of the file.
  378.  
  379. run"dumpfile
  380.  
  381. DUMPFILE: Enter filename.ext: ? suitea.bin
  382.  
  383. 0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  384. 0010: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  385. 0020: 02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  386. 0030: 03 03 03 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  387. 0040: 04 04 04 04 00 00 00 00 00 00 00 00 00 00 00 00 ................
  388. 0050: 05 05 05 05 05 00 00 00 00 00 00 00 00 00 00 00 ................
  389. 0060: 06 06 06 06 06 06 00 00 00 00 00 00 00 00 00 00 ................
  390. 0070: 07 07 07 07 07 07 07 00 00 00 00 00 00 00 00 00 ................
  391. 0080: 08 08 08 08 08 08 08 08 00 00 00 00 00 00 00 00 ................
  392. 0090: 09 09 09 09 09 09 09 09 09 00 00 00 00 00 00 00 ................
  393. 00A0: 0A 0A 0A 0A 0A 0A 0A 0A 0A 0A 00 00 00 00 00 00 ................
  394. 00B0: 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 00 00 00 00 00 ................
  395. 00C0: 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C 0C 00 00 00 00 ................
  396. 00D0: 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 0D 00 00 00 ................
  397. 00E0: 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 0E 00 00 ................
  398. 00F0: 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 0F 00 ................
  399.  
  400. Ok
  401. run"bytestat
  402.  
  403. BYTESTAT: Enter filename.typ : ? suitea.bin
  404.  
  405. Percentages of bytes usage inside file SUITEA.BIN.
  406.  
  407. % | .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F
  408. --+------------------------------------------------
  409. 0.| 53  0  1  1  2  2  2  3  3  4  4  4  5  5  5  6
  410. 1.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  411. 2.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  412. 3.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  413. 4.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  414. 5.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  415. 6.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  416. 7.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  417. 8.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  418. 9.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  419. A.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  420. B.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  421. C.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  422. D.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  423. E.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  424. F.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  425.  
  426. Do you want a histogram? (y/N) y
  427.  
  428. 00|::::::::::::::::::::::::::.
  429. 01|
  430. 02|.
  431. 03|.
  432. 04|:
  433. 05|:
  434. 06|:
  435. 07|:.
  436. 08|:.
  437. 09|::
  438. 0A|::
  439. 0B|::
  440. 0C|::.
  441. 0D|::.
  442. 0E|::.
  443. 0F|:::
  444.  
  445. Ok
  446.  
  447. As can be seen (I  hope), the  program produces  correct values.
  448. Now that we have some confidence in the program, let us see what
  449. it displays when computing the percentage of use of bytes inside
  450. WS4 files.
  451.  
  452. run"bytestat
  453.  
  454. BYTESTAT: Enter filename.typ : ? printtst.ws4
  455.  
  456. Percentages of bytes usage inside file PRINTTST.WS4.
  457.  
  458. % | .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F
  459. --+------------------------------------------------
  460. 0.|  0  0  1  0  0  0  0  0  0  0  3  0  0  2  0  0
  461. 1.|  0  0  0  0  0  0  0  0  0  0  1  1  3  0  0  0
  462. 2.| 21  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0
  463. 3.|  0  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  464. 4.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  465. 5.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  466. 6.|  0  4  1  3  1  4  1  0  2  4  0  0  2  1  3  3
  467. 7.|  2  0  3  1  4  1  0  1  0  0  0  0  0  0  0  0
  468. 8.|  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0
  469. 9.|  0  0  0  0  0  0  0  0  0  0  0  2  0  0  0  0
  470. A.|  2  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  471. B.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  472. C.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  473. D.|  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  474. E.|  0  0  0  0  1  2  0  0  0  0  0  0  0  0  1  0
  475. F.|  0  0  1  1  1  0  0  0  0  0  0  0  0  0  0  0
  476.  
  477. Do you want a histogram? (y/N) n
  478.  
  479. Ok
  480.  
  481. Big surprise! 21% of usage by 20h (that is to say: "space"). One
  482. char out of five in a WS4 file is a space... We must, for  sure,
  483. treat "spaces" before any other characters when scanning a file!
  484.  
  485. Another surprise is that none of the uppercase  letters (41h  to
  486. 5Ah) make it, despite so much sentences starting with a  A or  a
  487. T. Instead, notice the  percentage of  use of  lowercase letters
  488. (61h to 7Ah), and particularly "a" (4%), "e" (4%), "i"  (4%) and
  489. "t" (4%). This time, we find "a" and "t", but not in the case we
  490. were expecting.
  491.  
  492. This  above  table  provides  a  fascinating  view  inside   the
  493. internals of WordStar 4. But I won't bore you with the details.
  494.  
  495. Since  writing  this program  (you will  find a  summary of  the
  496. listing below.  The missing lines  are just  repetitions of  the
  497. enclosing patterns), I have  been wondering  what other  uses it
  498. could be applied to?  If you have any idea, let us know.
  499.  
  500. list
  501. 10 REM BYTESTAT.BAS  by Emmanuel ROCHE
  502. 20 :
  503. 30 PRINT
  504. 40 INPUT "BYTESTAT: Enter filename.typ : " ; file$
  505. 50 PRINT
  506. 60 nofile$ = FIND$ (file$)
  507. 70 IF nofile$ = "" THEN PRINT CHR$ (7) "File not found." : PRINT : END
  508. 80 OPTION BASE 0
  509. 90 DIM t (&HFF)
  510. 100 tot = 0
  511. 110 OPEN "R", 1, file$, 1
  512. 120 FIELD #1, 1 AS byte$
  513. 130 :
  514. 140 GET #1
  515. 150 IF EOF (1) THEN GOTO 230
  516. 160 byte = ASC (byte$)
  517. 170 hini = INT (byte / 16)
  518. 180 loni = byte - hini * 16
  519. 190 GOSUB 510
  520. 200 tot = tot + 1
  521. 210 GOTO 140  ' Main Loop
  522. 220 :
  523. 230 PRINT "Percentages of bytes usage inside file " UPPER$ (file$) "."
  524. 240 PRINT
  525. 250 PRINT "% | .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .A .B .C .D .E .F"
  526. 260 PRINT "--+------------------------------------------------"
  527. 270 FOR i = 0 TO &HF
  528. 280     PRINT HEX$ (i) ".|" ;
  529. 290     FOR j = 0 TO &HF
  530. 300         PRINT " " USING "##" ; (t (i * 16 + j) ) * 100 / tot ;
  531. 310     NEXT j
  532. 320     PRINT
  533. 330 NEXT i
  534. 340 PRINT
  535. 350 :
  536. 360 z$ = "" : PRINT "Do you want a histogram? (y/N) " ;
  537. 370 z$ = INPUT$ (1)
  538. 380 z$ = UPPER$ (z$)
  539. 390 IF z$ <> "Y" THEN PRINT : GOTO 480
  540. 400 :
  541. 410 PRINT : PRINT
  542. 420 FOR k = 0 TO &HFF
  543. 430     IF t (k) < 1 THEN GOTO 460
  544. 440     PRINT RIGHT$ ("0" + HEX$ (k), 2) "|" ;
  545. 450     IF t (k) * 100 / tot MOD 2 = 0  THEN PRINT STRING$
  546.         ( (t (k) * 100 / tot) / 2, ":") ELSE PRINT STRING$
  547.         ( (t (k) * 100 / tot - 1) / 2, ":") "."
  548. 460 NEXT k
  549. 470 :
  550. 480 PRINT
  551. 490 END
  552. 500 :
  553. 510 ' High Nibble:    0    1    2    3    4     5     6     7
  554. 520 ON hini+1 GOSUB 600, 680, 760, 840, 920, 1000, 1080, 1160
  555. 530 IF hini > 7 THEN hini2 = hini - 7 ELSE RETURN
  556. 540 ' High Nibble:    8     9     A     B     C     D     E    F
  557. 550 ON hini2 GOSUB 1240, 1320, 1400, 1480, 1560, 1640, 1720, 1800
  558. 560 RETURN
  559. 570 '
  560. 580 ' High Nibble: 0
  561. 590 ' Low Nibble:      0     1     2     3     4     5     6     7
  562. 600 ON loni+1 GOSUB 1870, 1910, 1950, 1990, 2030, 2070, 2110, 2150
  563. 610 IF loni > 7 THEN loni2 = loni - 7 ELSE RETURN
  564. 620 ' Low Nibble:     8     9     A     B     C     D     E     F
  565. 630 ON loni2 GOSUB 2190, 2230, 2270, 2310, 2350, 2390, 2430, 2470
  566. 640 RETURN
  567.  
  568. 1770 '
  569. 1780 ' High Nibble: F
  570. 1790 ' Low Nibble:       0      1      2      3      4      5      6      7
  571. 1800 ON loni+1 GOSUB 11470, 11510, 11550, 11590, 11630, 11670, 11710, 11750
  572. 1810 IF loni > 7 THEN loni2 = loni - 7 ELSE RETURN
  573. 1820 ' Low Nibble:      8      9      A      B      C      D      E      F
  574. 1830 ON loni2 GOSUB 11790, 11830, 11870, 11910, 11950, 11990, 12030, 12070
  575. 1840 RETURN
  576. 1850 '
  577. 1860 ' 00
  578. 1870 T (&H0) = T (&H0) + 1
  579. 1880 RETURN
  580.  
  581. 12050 '
  582. 12060 ' FF
  583. 12070 T (&HFF) = T (&HFF) + 1
  584. 12080 RETURN
  585. Ok
  586.  
  587. system
  588.  
  589. A>That's all, Folks!
  590.  
  591.  
  592. Yours Sincerely,
  593. "French Luser"
  594.  
  595.  
  596. EOF
  597.