<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:media="http://search.yahoo.com/mrss/"
>

<channel>
	<title>FormatStyle &#8211; Wade Tregaskis</title>
	<atom:link href="https://wadetregaskis.com/tags/formatstyle/feed/" rel="self" type="application/rss+xml" />
	<link>https://wadetregaskis.com</link>
	<description></description>
	<lastBuildDate>Sat, 18 May 2024 20:43:12 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://wadetregaskis.com/wp-content/uploads/2016/03/Stitch-512x512-1-256x256.png</url>
	<title>FormatStyle &#8211; Wade Tregaskis</title>
	<link>https://wadetregaskis.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">226351702</site>	<item>
		<title>The only usable ByteCountFormatStyle is decimal</title>
		<link>https://wadetregaskis.com/the-only-usable-bytecountformatstyle-is-decimal/</link>
					<comments>https://wadetregaskis.com/the-only-usable-bytecountformatstyle-is-decimal/#respond</comments>
		
		<dc:creator><![CDATA[]]></dc:creator>
		<pubDate>Sat, 18 May 2024 20:43:10 +0000</pubDate>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[binary]]></category>
		<category><![CDATA[binary prefix]]></category>
		<category><![CDATA[Bugs!]]></category>
		<category><![CDATA[ByteCountFormatStyle]]></category>
		<category><![CDATA[decimal]]></category>
		<category><![CDATA[FormatStyle]]></category>
		<category><![CDATA[SI units]]></category>
		<category><![CDATA[Swift]]></category>
		<guid isPermaLink="false">https://wadetregaskis.com/?p=8165</guid>

					<description><![CDATA[Swift makes it relatively easy to format numbers as byte counts, with appropriate suffixes to indicate units and generally sensible auto-selection of scale factors. e.g.: 1 kB (in English &#8211; results may vary depending on locale) This is just a small subset of Swift&#8217;s FormatStyle-based formatting capabilities, with which I have a bit of a&#8230; <a class="read-more-link" href="https://wadetregaskis.com/the-only-usable-bytecountformatstyle-is-decimal/" data-wpel-link="internal">Read more</a>]]></description>
										<content:encoded><![CDATA[
<p>Swift makes it relatively easy to format numbers as byte counts, with appropriate suffixes to indicate units and generally sensible auto-selection of scale factors.  e.g.:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-disabled" data-code-block-pro-font-family="" style="font-size:.875rem;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #098658">1234</span><span style="color: #000000">.</span><span style="color: #795E26">formatted</span><span style="color: #000000">(.</span><span style="color: #795E26">byteCount</span><span style="color: #000000">(</span><span style="color: #795E26">style</span><span style="color: #000000">: .</span><span style="color: #001080">decimal</span><span style="color: #000000">))</span></span></code></pre></div>



<figure class="wp-block-pullquote"><blockquote><p>1 kB</p><cite>(in English &#8211; results may vary depending on locale)</cite></blockquote></figure>



<p>This is just a small subset of Swift&#8217;s <code><a href="https://developer.apple.com/documentation/foundation/formatstyle" data-wpel-link="external" target="_blank" rel="external noopener">FormatStyle</a></code>-based formatting capabilities, with which <a href="https://wadetregaskis.com/fucking-formatstyle/" data-wpel-link="internal">I have a bit of a love-hate relationship</a> even when they&#8217;re working correctly.</p>



<p>Alas, they don&#8217;t always work correctly; some of these formatters contain egregious bugs.</p>



<p>In particular, <code>ByteCountFormatStyle</code> pretends to support multiple numeric bases &#8211; decimal and binary &#8211; but it doesn&#8217;t, because what it renders for binary is:</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-disabled" data-code-block-pro-font-family="" style="font-size:.875rem;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #098658">1234</span><span style="color: #000000">.</span><span style="color: #795E26">formatted</span><span style="color: #000000">(.</span><span style="color: #795E26">byteCount</span><span style="color: #000000">(</span><span style="color: #795E26">style</span><span style="color: #000000">: .</span><span style="color: #001080">binary</span><span style="color: #000000">))</span></span></code></pre></div>



<figure class="wp-block-pullquote"><blockquote><p>1 kB</p><cite>(in English &#8211; results may vary depending on locale)</cite></blockquote></figure>



<p>Note how it still uses <em>decimal</em> units, &#8220;kB&#8221;.  Decimal is not binary.  I mean, duh, right?  But apparently Apple don&#8217;t know this.</p>



<div class="wp-block-group"><div class="wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained">
<p>☝️ <a href="https://en.wikipedia.org/wiki/Binary_prefix" data-wpel-link="external" target="_blank" rel="external noopener">Binary prefix</a> abbreviations are always two characters, the second always &#8220;i&#8221;.  In this case, &#8220;KiB&#8221;<sup data-fn="360480d9-2d8c-44ac-ae55-be1417b55320" class="fn"><a href="#360480d9-2d8c-44ac-ae55-be1417b55320" id="360480d9-2d8c-44ac-ae55-be1417b55320-link">1</a></sup>.  They&#8217;re easy to remember because they use the same first letter as their decimal cousins, e.g. &#8220;Ti&#8221; &amp; &#8220;T&#8221; for tebi and tera.  Their derivation is really simple &#8211; take the first two letters of the decimal cousin, e.g. &#8220;te&#8221;, and the first two letters from &#8220;binary&#8221;, &#8220;bi&#8221; &#8211; voilà, &#8220;tebi&#8221;.  To abbreviate, just drop the middle letters and use titlecase.</p>
</div></div>



<h2 class="wp-block-heading">So what?</h2>



<p>While the above example is tolerable because, given the rounding applied, the numeric result (&#8220;1&#8221;) is technically corrected in both bases, see what happens when you use larger values:</p>



<figure class="wp-block-table aligncenter"><table><thead><tr><th class="has-text-align-right" data-align="right">Input number</th><th class="has-text-align-center" data-align="center"><code><a href="https://developer.apple.com/documentation/foundation/bytecountformatstyle/style/decimal" data-wpel-link="external" target="_blank" rel="external noopener">decimal</a></code></th><th class="has-text-align-center" data-align="center"><code><a href="https://developer.apple.com/documentation/foundation/bytecountformatstyle/style/binary" data-wpel-link="external" target="_blank" rel="external noopener">binary</a></code></th></tr></thead><tbody><tr><td class="has-text-align-right" data-align="right">1,000</td><td class="has-text-align-center" data-align="center">1 kB</td><td class="has-text-align-center" data-align="center">1,000 bytes</td></tr><tr><td class="has-text-align-right" data-align="right">1,024</td><td class="has-text-align-center" data-align="center">1 kB</td><td class="has-text-align-center" data-align="center">1 kB</td></tr><tr><td class="has-text-align-right" data-align="right">1,000,000</td><td class="has-text-align-center" data-align="center">1 MB</td><td class="has-text-align-center" data-align="center">977 kB</td></tr><tr><td class="has-text-align-right" data-align="right">1,048,576</td><td class="has-text-align-center" data-align="center">1 MB</td><td class="has-text-align-center" data-align="center">1 MB</td></tr><tr><td class="has-text-align-right" data-align="right">1,000,000,000</td><td class="has-text-align-center" data-align="center">1 GB</td><td class="has-text-align-center" data-align="center">953.7 MB</td></tr><tr><td class="has-text-align-right" data-align="right">1,073,741,824</td><td class="has-text-align-center" data-align="center">1.07 GB</td><td class="has-text-align-center" data-align="center">1 GB</td></tr><tr><td class="has-text-align-right" data-align="right">1,000,000,000,000</td><td class="has-text-align-center" data-align="center">1 TB</td><td class="has-text-align-center" data-align="center">931.32 GB</td></tr><tr><td class="has-text-align-right" data-align="right">1,099,511,627,776</td><td class="has-text-align-center" data-align="center">1.1 TB</td><td class="has-text-align-center" data-align="center">1 TB</td></tr><tr><td class="has-text-align-right" data-align="right">1,000,000,000,000,000</td><td class="has-text-align-center" data-align="center">1 PB</td><td class="has-text-align-center" data-align="center">909.49 TB</td></tr><tr><td class="has-text-align-right" data-align="right">1,125,899,906,842,624</td><td class="has-text-align-center" data-align="center">1.13 PB</td><td class="has-text-align-center" data-align="center">1 PB</td></tr></tbody></table></figure>



<p>Once you get up to non-trivial byte counts, you start to get different results even with the heavy rounding that&#8217;s applied by default.  By the time you&#8217;re talking about GBs the error is on the order of 10%.  And the error just gets proportionately larger as the input number increases.  <a href="https://en.wikipedia.org/wiki/Binary_prefix#Comparison_of_binary_and_decimal_prefixes" data-wpel-link="external" target="_blank" rel="external noopener">Wikipedia has a neat little table showing this</a>.</p>



<h2 class="wp-block-heading">Okay, but that&#8217;s just <code>binary</code>, what about <code><a href="https://developer.apple.com/documentation/foundation/bytecountformatstyle/style/file" data-wpel-link="external" target="_blank" rel="external noopener">file</a></code> and <code><a href="https://developer.apple.com/documentation/foundation/bytecountformatstyle/style/memory" data-wpel-link="external" target="_blank" rel="external noopener">memory</a></code>?</h2>



<p>Those are just aliases to <code>decimal</code> and <code>binary</code>, respectively.  So <code>memory</code> is right out.</p>



<p>You might think <code>file</code> is still okay, because it essentially means <code>decimal</code>.  But that&#8217;s only <em>currently</em>.  The entire point of its existence is to allow its behaviour to change over time, following whatever convention Apple believes is most appropriate for files.  In the past that was in fact <code>binary</code>, as noted previously (pre-Snow Leopard).  It might be <code>binary</code> again in future.  So it&#8217;s dangerous to use since you can neither know what units it&#8217;s going to use nor whether Apple will have fixed their formatters by the time it switches off of <code>decimal</code>.</p>



<h2 class="wp-block-heading">But context will save us!</h2>



<p>Probably not.  Go look at file sizes in the macOS Finder.  Can you tell whether they&#8217;re actual decimal (as they appear) or binary?</p>



<p>They&#8217;re <em>decimal</em>, but they <em>used</em> to be binary, <a href="https://www.macworld.com/article/199831/snow_leopard_math.html" data-wpel-link="external" target="_blank" rel="external noopener">up until Mac OS X Snow Leopard (10.6)</a>.  And the Finder used the <em>same</em> (decimal) unit abbreviations throughout.  So at least it&#8217;s using the correct units now &#8211; almost by accident &#8211; but it created a confused transition and history.</p>



<p>Worse and more presently pertinent, not everything Finder-like uses decimal, nor correct units when they don&#8217;t.  e.g. <a href="https://superuser.com/questions/1519532/why-do-mac-and-synology-report-different-file-sizes" data-wpel-link="external" target="_blank" rel="external noopener">Synology&#8217;s products</a>, not to mention countless websites.  That creates a lot of confusion which bleeds across into even well-behaved software.</p>



<p>Point being, you both can&#8217;t rely on context to help, because context includes things you can&#8217;t control like other software, and by getting the units wrong you&#8217;re making it worse for everyone, not just yourself.</p>



<h2 class="wp-block-heading">Why is this still happening?</h2>



<p>Going back twenty years, this kind of error &#8211; confusing decimal with binary w.r.t. unit prefixes &#8211; was both the norm and <em>somewhat</em> excusable &#8211; binary prefixes were <a href="https://en.wikipedia.org/wiki/IEC_60027" data-wpel-link="external" target="_blank" rel="external noopener">only formally standardised upon in 1999</a>, so it&#8217;s only to be expected that it will take some time for everyone to adopt them.</p>



<p>But it&#8217;s been a quarter of a century already.  There is absolutely no excuse anymore for getting this wrong.</p>


<ol class="wp-block-footnotes"><li id="360480d9-2d8c-44ac-ae55-be1417b55320">If you&#8217;re paying attention you&#8217;ll have noticed &#8220;k&#8221; vs &#8220;K&#8221;, i.e. the difference in case.  This is not arbitrary &#8211; it&#8217;s because units have to be distinct to be functional, and &#8220;K&#8221; is the abbreviation for Kelvin (and apparently wins because it&#8217;s one of <a href="https://en.wikipedia.org/wiki/SI_base_unit" data-wpel-link="external" target="_blank" rel="external noopener">the seven <em>base</em> physical units</a>, from which pretty much all other physical units are derived).<br><br>&#8220;Ki&#8221; is fine because it&#8217;s a distinct prefix (and &#8220;i&#8221; is not a valid abbreviation by itself so there&#8217;s no potential confusion about whether it means &#8220;Kelvin • i&#8221; or &#8220;kibi&#8221;). <a href="#360480d9-2d8c-44ac-ae55-be1417b55320-link" aria-label="Jump to footnote reference 1">↩︎</a></li></ol>]]></content:encoded>
					
					<wfw:commentRss>https://wadetregaskis.com/the-only-usable-bytecountformatstyle-is-decimal/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">8165</post-id>	</item>
		<item>
		<title>Fucking FormatStyle</title>
		<link>https://wadetregaskis.com/fucking-formatstyle/</link>
					<comments>https://wadetregaskis.com/fucking-formatstyle/#comments</comments>
		
		<dc:creator><![CDATA[]]></dc:creator>
		<pubDate>Sat, 18 May 2024 20:25:05 +0000</pubDate>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[ByteCountFormatStyle]]></category>
		<category><![CDATA[FormatStyle]]></category>
		<category><![CDATA[Swift]]></category>
		<guid isPermaLink="false">https://wadetregaskis.com/?p=8181</guid>

					<description><![CDATA[I have a bit of a love-hate relationship with Swift&#8217;s FormatStyle-based formatting capabilities. 42% (in English &#8211; results may vary depending on locale) On the pro side: But the cons are rough: All in all, there&#8217;s a reason fuckingformatstyle.com exists (and don&#8217;t forget to tip!).]]></description>
										<content:encoded><![CDATA[
<p>I have a bit of a love-hate relationship with Swift&#8217;s <code><a href="https://developer.apple.com/documentation/foundation/formatstyle" data-wpel-link="external" target="_blank" rel="external noopener">FormatStyle</a></code>-based formatting capabilities.</p>



<div class="wp-block-kevinbatdorf-code-block-pro padding-disabled" data-code-block-pro-font-family="" style="font-size:.875rem;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><pre class="shiki light-plus" style="background-color: #FFFFFF" tabindex="0"><code><span class="line"><span style="color: #795E26">Text</span><span style="color: #000000">(progress.</span><span style="color: #795E26">formatted</span><span style="color: #000000">(.</span><span style="color: #001080">percent</span><span style="color: #000000">.</span><span style="color: #795E26">precision</span><span style="color: #000000">(.</span><span style="color: #795E26">significantDigits</span><span style="color: #000000">(</span><span style="color: #098658">2</span><span style="color: #000000">))))</span></span></code></pre></div>



<figure class="wp-block-pullquote"><blockquote><p>42%</p><cite>(in English &#8211; results may vary depending on locale)</cite></blockquote></figure>



<p>On the pro side:</p>



<ul class="wp-block-list">
<li>They&#8217;re better than rolling your own formatting. Not just in terms of convenience, but in terms of correctness &#8211; they support localisation, for example.  &#8220;42%&#8221; in English, &#8220;٤٢٪؜&#8221; in العربية (Arabic), &#8220;৪২%&#8221; in অসমীয়া (Assamese), &#8220;42 %&#8221; in Deutsch (German), etc.</li>



<li>They&#8217;re terser than using their otherwise more powerful cousins the <code><a href="https://developer.apple.com/documentation/foundation/formatter" data-wpel-link="external" target="_blank" rel="external noopener">Formatter</a></code>s, as they support a &#8220;fluent&#8221; style of property-based access, which tends to read more naturally and usually avoids having to define variables to hold the formatter.</li>
</ul>



<p>But the cons are rough:</p>



<ul class="wp-block-list">
<li>They almost always break Xcode&#8217;s auto-complete, which is a problem since their syntax is non-trivial and unintuitive.</li>



<li>They&#8217;re hard to understand &#8211; and to even find in Apple&#8217;s official documentation &#8211; because there&#8217;s so many protocols and indirection involved.<br><br>It&#8217;s particularly hard to tell where the inexplicable gaps are. e.g. <code><a href="https://developer.apple.com/documentation/swift/double" data-wpel-link="external" target="_blank" rel="external noopener">Double</a></code> doesn&#8217;t support <code><a href="https://developer.apple.com/documentation/foundation/bytecountformatstyle" data-wpel-link="external" target="_blank" rel="external noopener">ByteCountFormatStyle</a></code>, even though logically it should <em>and</em> Xcode will sometimes auto-complete as if it does. Worse, there&#8217;s often no valid compiler diagnostic if you try to use them together &#8211; you just get a long hang and eventually the dreaded &#8220;unable to type check in a reasonable time&#8221; cop-out.</li>
</ul>



<p>All in all, there&#8217;s a reason <a href="https://fuckingformatstyle.com" data-wpel-link="external" target="_blank" rel="external noopener">fuckingformatstyle.com</a><sup data-fn="ab1d5ba0-795f-4f9c-81d6-b44c94903168" class="fn"><a href="#ab1d5ba0-795f-4f9c-81d6-b44c94903168" id="ab1d5ba0-795f-4f9c-81d6-b44c94903168-link">1</a></sup> exists (and <a href="https://ko-fi.com/ampersandsoftworks" data-wpel-link="external" target="_blank" rel="external noopener">don&#8217;t forget to tip</a>!).</p>


<ol class="wp-block-footnotes"><li id="ab1d5ba0-795f-4f9c-81d6-b44c94903168">There&#8217;s also the alias <a href="https://goshdarnformatstyle.com" data-wpel-link="external" target="_blank" rel="external noopener">goshdarnformatstyle.com</a> if you want to pretend anybody doesn&#8217;t know exactly what you actually mean.  I assure you that the stronger expletive is by far the most appropriate, once you have experience with <code>FormatStyle</code>. <a href="#ab1d5ba0-795f-4f9c-81d6-b44c94903168-link" aria-label="Jump to footnote reference 1">↩︎</a></li></ol>]]></content:encoded>
					
					<wfw:commentRss>https://wadetregaskis.com/fucking-formatstyle/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">8181</post-id>	</item>
	</channel>
</rss>
