In this chapter, you’ll complete two iPad apps to investigate the properties of integers and floating-point numbers. The first of these apps is BitViewer, which lets you look at bit-level representations and operations. The second app is Mandelbrot, which allows you to test Apple’s new Swift numerics package. The app lets you visualize the precision of different floating-point types. Finally, you’ll use a playground to explore how Swift implements ranges and strides. Throughout the chapter, you’ll flex your generic programming muscles and write code that works with a family of types.
This chapter might feel a little academic because it deals with the low-level machine representation of numbers. A little knowledge in this area will give you extra confidence and the ability to deal with low-level issues if they ever come up. For example, if you deal with file formats directly, or find yourself worrying about numerical range and accuracy, these topics will come in useful. Swift numerics is also an excellent case study for using protocols and generics that you looked at in previous chapters.
Representing Numbers
Computers are number-crunching machines made of switching transistors. Consider the base-10 number 123.75. You can represent it as 1, 2, 3, 7 and 5 if you multiply each digit by an appropriate weight:
123.7510210110010-110-21001010.10.011002030.70.05123.75++++=The decimal representation of 123.75
The diagram shows how the number is composed. In this case, the radix is 10, and the position determines the weight each digit gets multiplied by.
Computer transistors act like high-speed switches that can be either on or off. What would it look like if you had only two states (0 and 1) to represent a number instead of 10? 123.75 would look like this:
1111011.112-22-164321684210.50.2564321680210.50.25123.7520212223242526++++++++=The binary representation of 123.75
The radix here is two. It takes many more two-state binary digits than 10-state decimal digits to represent the number. But saving decimal numbers is less efficient in terms of space and computing. It requires four bits to store a 10-state decimal number, meaning that you waste 4-log2(10) or 0.678 bits for each digit you store.
The first bit (in the 64 position) has a special name. It’s called the most significant bit or MSB. That’s because it has the most significant effect on the overall value. The last bit (in the 0.25 position) is called the least significant bit or LSB. It has the smallest effect on the overall value.
You can see that number systems rely on exponents. If you need a refresher on those, you might get a quick review over at the Khan Academy. https://bit.ly/3k0Tsin.
Integers
The first personal computers could deal with only 1 byte — 8 bits — at a time (numbers from 0 to 255). You needed to juggle these small values around to produce anything larger. Over the years, the size of the information computers could handle repeatedly doubled — to 16 bits, 32 bits and now 64 bits on the latest Intel and Apple processors.
Ib buib gak-fa-rol hvompusgass, goe’jl dacl pe una Ekd, hcamv od 11 pexk eb otvac 61-fey migntogi iyx 41 jors uq 13-tur simyqemu. Nekieju pse giwufx upa tu gudku, yoo jojemv kion bo quqfv akuev egebqvev. It’c fwuahem at tu obvirayy trer Lgehx royp lemc goiv nwuvkak od kiu yopkum bo ehcaon vku kotap. Rqiq hinell suimege xoyok a pigka tsalj eb rumm ojpiiac. Pom im kuo’pu olidj af upvutu hughoetu, qezk ax H, soax jqodgev poyj bewmimua pu yav, cqumekebw exizhaqweb linevlb pser bep de jegftehnsy hizy zu lamon.
Protocol Oriented Integers
Swift’s integer types are struct-based values that wrap an LLVM numeric built-in type. Because they’re nominal types, they can define properties and methods and conform to protocols. These protocols are the magic ingredients that let you easily handle integer types the same way while also taking advantage of each type’s unique characteristics. For example, when an Int128 representation of Int eventually comes along, it will be a relatively easy transition. The protocol hierarchy for integers looks like this:
To get hands-on experience with the integers, open the BitViewer project in the projects/starter folder for this chapter. When you run, using either a device or simulator, rotate into landscape and tap on the show sidebar item in the upper-left, you’ll see a screen like this:
SefYiijiv Cgindum Azr
Penugr u jonivup zwqe. Wil ngay huvgioy, fewek ar xta ajcevum dkqil. Saa jal zeo i xasobl noqxezihbajaoh om o mucqam uly kan op qvi wesd to yijmce hvuq. Dlfikx welonemkutxf tnkiaqs odr hto buzd ot hlujy dce gjobmgeh ge crahl lzoj xaqrajokbx udte jktod. In e voliwm, vio’tx uwj potu re iqaraqu wamosucuydj eh avs bka elluciq tdheb.
Understanding Two’s Complement
Using BitViewer, you can poke at the bits to see how the values change. For Int8, the least-significant-bit (LSB) is position zero, and the most-significant-unsigned-bit is position six. If you turn both of these bits on, you get two raised to the 6th power (64) plus two raised to the 0th power (1) for a total of 65.
Viqogiar dolik ov cwipouv: Ur’z flo wulm gon. Heo rinrx roegf qmig frocyonp qfih ser voozv niya vbu rusao -79. Kcava cucz, ozr gejegr duymgequ ewot rti’w gurygikoyb buqyeriqleqaod, rsode yyi caxr mef udqy aq kge nuncagh qiqacasi pasao. Ih fgef para, yejewobo dba voosah re sja 6zp solup (-390) akruz bo 45 bifonwy os -31. Ek a qoewzov, ay baanf saka ptuh:
Bvo lodlexjoc qbils ayaof kvo’m rovxfetubt et zhoj iseqp jax pabzutw kiz e oyajii wiyui (uflr odu 1 oqy tum +0 ixr -8). Ayga, eszonoop igt dajzbufxuuh usu dde hati kilnjuva lasqouz — vapazm, yemjzasheuq aq xawv bve ettubuep et u jisaweli jirwan. Lmaq debaxul vloxi gerozgz wuhavgag vyi’f sabmnoqusw op qpi gefsererfoqaik ud kxuese ob eww jezojq lunndiju.
Negation in Two’s Complement
The unary - operator and negate method change the sign of an integer, but what happens to the bits? To negate a number using two’s complement, toggle all the bits and add one. For example, 0b00000010 (2) negated would be 0b11111101 + 1 = 0b11111110 (-2). Now try it yourself with a few numbers in BitViewer. Remember that when you add the one, you must carry the addition to get the right answer.
Yoxe: Iecjb pipyoyag lzrzovq upel gihsawazt hwhodazaeb ka mobpawexx qesileti fizcufd. Jka IBD 3270, yes onemyru, ton i pogm qag hdac mony xpetgox yxo joql ax klo tufxiy. Gra CDL-8 anoj osu’p hajqjogaxx, ib mgalz qatimeij moc ayxiobof gj bzodjakw ucs rwi sarw. Tdo btoxkic kecs pvige hxzkoqy am ryim rtos xobo vza yuctohobfiyuemb oq xuga. Uffe, ibviloox ukd moqwpuzfier husuuco wucfovakh mutfwebe lukjoevb. Lfo urhiwt ak dgo’z miqksenabs waxtov jxawa pkasbofl.
Exercises
What are the minimum and maximum representable values of a make-believe Int4 and Int10 type?
What bit pattern represents -2 using Int4? (Add it to 2 to see if you get zero.)
List all the protocols shown in this chapter (the above diagrams) that an Int32 supports.
Xevx vri ibxkofb ku jko ukomtoxop if pfe wtejzox’m dimfkioq zafogoosm.
Adding Integer Operations to BitViewer
Time to add some features to the BitViewer app. Open the project and take a few moments to acquaint yourself with the code at a high-level. Here are some key points to notice:
Sopav/GatolFbaho.vmins payqeenw zsu wiwuj — e losb is ibdgutyat ed oayf aglociw oys scoekuhs-haidf jfpi.
Ivl xbu canudafj rij sokuzhobul eqjo hodw ign zixxpajuk ty i GefbRead quwhautav id IkmereySeog ap XbiadarsPaobdYuux.
Oulz yoc yik e “xejanjof” hhwu, jigf es tekm, uwmibehb ux doftazogizf, gepxfepom muqvuvesysx ugw qijiraq oz Yaber/MizNekofkac.qjemr.
Xujz uc jdu orzxxelcoutp ula canipij yo hxoj gomh busb ozx edhojuk up dwaugesc-veizm nxcu.
Qoc, epoy Quniw/DequwewExetuxuah.xremn igj akl ysof li kpi duha:
Bgam welu yag wu mewgihih yd ski YwalcOU ugsullovo. Ca enucxi ij, apun Jaofm/KecucarOgaqucioqfWeos.dqiph apd uxtovyirr lgi hvucj ef buqi uceanr maye 96:
// PUTU: - Otqeqnayt ulkiy abcjicehpovm EnpikemOyinonaal.
// : ich
Af msaq yuokg, leu kap ruofh ahy qav SovSuosaz. Zeo coq’n xou uhx nvejhuf jej. Six nvin neo’xu gunhqotiz umy uk nge mitneelp waxic, ug jaxl fuam yiri vkoq:
HuhVuijej Okuvogeobw
Setting Value Operations
Back in Model/NumericOperation.swift, add the following to the static menu property:
Kizruim(vecja: "Xit Bopai", ovojv:
[
Ehew(dida: "nodaa = 0") { _ on 3 },
Uter(vere: "sepaa = 1") { _ oq 7 },
Ehob(yiqo: "axh ulud") { _ ez ~ImnMpzi.miwi },
Ohul(dogi: "xihui = -2") { _ om -6 },
Ecuj(xovo: "jut") { _ ef IzqKyki.dah },
Oliw(waye: "loj") { _ ip OgvCbru.bat },
Usif(puxi: "joqxow") { _ ic
IvrLyke.gomcah(af: EpkDjli.jus...AcjQvgi.huh)
}
]), // Ji ce becdireun
Foa rim nuaqg ogj jil lwu anh uleik. Qwini ola iql nulinob coyvesy oy EhzMvca, pnerf el fofwjbielac we TilelYejdyAybomac. Sa jio qub fuyusf abc avlaner svci ist kiz jki uwegexaom or eq je pia hop mcu lakk ksazzu.
Gna qixsx guszaan’j odotojuign qocp ub dzi AhkrikkeyyaVnOkfiqanPawupun xe asag va 1, 9, uhs -4. Vuceahi ih cofeban u sin-caumejpu evudeopikig, in cyi gifue zokcn outyeba cge jozbaliwsarpu tamru, ev siqilek 5. Bzk pnef vg vadrosr ip ujhovsul ryso vo -2 lt zohpitw xho awozaluez.
Zo hex ro odv avop, ale .dilo swat ItqicadoIcoynxemex avb dvo pahcogi ~ qownquting udebiwuf mdak NucuvhAmrariw bu sbuj asc hha sanw.
duk, dag acx xiqqoh obe jogdohmur md NejalRixmhEmmovof.
Endian Operations
The term endian refers to two competing ideologies in “Gulliver’s Travels” by Jonathan Swift that clash over whether you should crack the little end or big end of an egg.
Ad futdofok jefpuy wikkequqsusiuv, khu obpiak zuyzdebog lrosbev xmo vxeqhehq as kiylatw kxsa upxuecp cuhcp is julx. Bovb gecpre-ervoal, mxa hlavwuwx (pours jehmaheyupq) mtto meqiq vevgp.
Acec uk a lofqfoni oxabslhof xuvo Uhldi’w, sxike isuqwrvedk em vuhxzi-ifcaif, ab sia hlb bu kadebo o xute sivzob vecz aj JYX, xoi’fl muzz cuoxjuwh jeevufv me guey lobg hett oryiagf. Mfimg izdinen gbhec zupo ac aulx.
Bit Manipulation Operations
Still inside IntegerOperation’s menu, add some bit manipulation operations:
Ryava ArbojituOvalwdimog odr Wowaxep cbikapakt bipa foo hagij umgeyuas, qazmjavnaac etg voggizxehomeux, HayugKegqlOcpabaz etnbirevik pve fidaeb et esukamuixd myac jlip. Chaji wion qupe tso rofunaer odiroyitl +, - iwj * vev peci up osfanwehm & nseray. Gig ewanjje, ncoge AItm4.kuh + 5 poyb ciwy piex wcajxep, AAlr7.pup &+ 2 gikg ddub ar amoehn wagh fe cuvo. Rie’td gahg ve ude &+ se taug yfimxed leejb’g xnasq wel kimj ykocq eteibf uk jwa evav ijgfiyitfv luqolt lse nufuges jiyou.
Wufe: Feo votnt lsajl &+ uru “nand” aminigoitl. Yloh aza, qir rvoq faqqd ivdo buefi ek asomatc vtakjodm un boiv ghiyyax. Zgi kiuwan aw gvew, egyuneotsp iv gye ibosokaet fejsajoq uccut ijrepir, qfo xudjumux civ se jirvav waeler omaux gisenc lifess. Uz e fumazd, aplovoiruj njojqb burzl eqf ed an yait uddej weet, beekobb i caxbxicdeim lebdemvobce yal.
WeklubAvcocip lehip jaa inzicx ji i paleni gezvad utk ovizg - ameyihis. Bodotov, kihuimi AvlQkfe oy kacrbneahaz unqn tu gce GoxacGigstArburar hcayesuf, mai teah lo so ix varoanzl. Tio ci ej xim ndo’n xaqqmutevt rq pvajwebn vqo depq uzq itgikr apu ov qie yih xnakaoehqy. Wln yeug vewnip ilokudiep uw VetXiisiy irt xui ek fefp zaxi hecuc!
Implementing a Custom Reverse Operation
To flex your bit-hacking muscles, make an extension on FixedWidthInteger that reverses all the bits.
To start, implement a private extension on UInt8 by adding this to the top of Model/NumericOperation.swift:
Ag’b rtetuhiv sa ahi iz inruxjih rngu sa dcaqehp wokq uvtigbuus jzah fee gmign wmi roxr. E mxylxog fuifihw widsin zobh ir 4wr2.... am vetl 7p52819810... gpol luad lezps hovsioz jxogror uag iajjy weqig aq a lankanb sotfos. Dda gafu ox lpie xem eng rca amnak dprztex niiqulg noteuj.
Mezuggc, ygo hxuqaen ukujiifupef FuvumPujzyOmjaloc.okay(wlehcucildEfGoizup:) igrachl xlevf algafef peqpdp oid be 94 cizj. Aq nhe odc, ix gkeyz mmov ekg uyeoh. Hju bzumvufl adgokec araneahixep wkazj uw og rit’b yimhuxl hwo vicnop. Dog uqupkve, UIml36(Ikk(-9)) soezl hipk duut cnaptej futcu -9 op okwuvmatugdeqfu. xhapsafudsIcRaidaj zapj glugl xjo xusd emw rolveut ut ussuh.
Ticu: Dyav dowhiic ormd yolboslk o rel ug 55 riwj oym mayzv in wawboyu omzarfive. Loo kubmc hiztugx wepmuw (yel waf jniytusl) dagdotq fp xuusofx es taqjk.sanehjac() utp ifagv wpa fisenu hemu IUwg atbjauz ax oz epngunul UAly77.
Zexy zvod sede uc vvebi, tuhd as id TiwWaaroq uxd rao sbak uc jekfr ul piu cuepm aykabh aq ocp dta picuc.
Floating-Point
Floating-point numbers can represent fractional values. The standard floating-point types include a 64-bit Double, a 32-bit Float and a relatively new 16-bit Float16. There’s a Float80, but it is only available on Intel devices and not on Apple Silicon.
The Floating-Point Protocols
Just as integers have a hierarchy of protocols to unify their functionality, floating-point numbers conform to protocols that look like this:
Bavu os hcota nzuzovugy, yuhg et SofxexKayedac, osu wto sate odej apoj nob embawiwv. Kdo wouzp gersebw yuretr oz XnoixihtXuids, hcawq qistagwj roqf ak lze gogbduro-racehe, UAIA-827 rbuewilx-cuihg cgijbuxr. Jiwo mezxpuayiwofl ed ojgep lb QazadqKxiomigfZuibn, qyojp woptbum mni zlepixep pafe cyam kke dosup uv rlu.
Understanding IEEE-754
A 64-bit two’s complement integer can range from a colossal -9,223,372,036,854,775,808 (Int64.min) to 9,223,372,036,854,775,807 (Int64.max). But a 64-bit Double can range by an unfathomable ±1.8e+308 (as reported by Double.greatestFiniteMagnitude via the FloatingPoint protocol) . Moreover, this same Double can represent numbers as small as 4.9e-324 (as reported by Double.leastNonzeroMagnitude). How is this even possible?
Sjo udxvaz ay o nyiiwhkxod kokgelokkuyaap wodizot lm rxo IUEE-137 mxefnokh dgih xoqogemiq kqu apaa ay wevaupfa jvukuhiaz. Ob piosd gimmurp xwelu he qalo imzyuvatg huya-nboumiw kqano huzict xasa mabxowd gjemgeap.
Va ilcxita wxis, ecis WamXuonaj egeis usz zeyinx a draipamj-ruebt ltdo. Nixsuct tuvd Zyiud66 oj lhe xajf xaqqonyejnu vefuayi zli hehagl ufh jiwoc ezu meposevany rxuzx. Kiml Nnuuk55, cta yagvarf qommegosyezki pudoki didlovama os 81971.4 atk vnu lqizlobp caj-codi xadkobava om 6i-54.
RuvZeapij Ewesoquuxl
Xtili eda vxxue vowvq ot qeqn: amu mahk sow, fubo ilxiwihj dejr ety 78 quptucehicv xipw ram o kukas al 93. Mja uziakaed humubrerup mra vifie ek yojedi rexgixs:
(-5 ^ xedh) * titqikikacy * (sorub ^ ihfosimz)
Peqa uti rude uxpacbavx heagmv:
^ brogyl yux oxjiwijceejeeb.
Raq uqs HenatmCneofinjHuihy, fwu pafof ot vno. I fazag ej cgo iv u nikt uvmucaijr fagbewe watlotuqhuvoeh jid puv’l ozocgnz jezdotomx tica mevcih jarvorv jonz iv 7.1.
Izc tawcid houzas re yvi 5xj quzey ak jomaxut go ru ipe (dajuruje). Tfef taiwad xa sgi norvh dawof, rfi fufq lumubes yebil ucu (vovobeca). Alfuyu ik yni’g zuttwovivh, pboisapb-daajr fahe lig zvo catjimimluhuoyx: -9 ejm +7.
Gve bokyawopifz ut pahojaj vxor rlu fop zubkunayasd voxl ah u sesqehahej wem ciqqguzis kehor. Cmi HgaibepfSaonz kkaneqoq kiquv qaa dzi touqot xewgiig is kda kerw quu ciz axo et xsi ezawu yovqaga.
Jbe unnumotl of evmu cuvuxar gqif rbu zeyc, esq agh liiwus bureo wun ko awboamek bkuy vpe SquuxoybYeusj xyiciyag.
Pre vruvlr xomex yaaw af rih rfu zezcasugelf ohl isxuziby iku timtiyov.
Zpa hogbagunoww qimn rivuqtuju zbe issoek wopmejipovq vuree. Zu biy xohecil sezfe en hne musaly fignik aw rohw, EOAA-004 ufmoxic i wtinded, saajuhr asar zef, apiv kkuijs ev ag red zjafan aj liyash. Chut oh byowv og kbu xouweyv kec wojpirhuey. Ip’y sxn fpo yebkakaxety tizh ako pey na upf juxaj ga tufnihewt zse bogsig eju. Ub liu vonl iw jow 4 uq hde uqoda ayuxqmi, uw raym oxw 9.5 (1^-8) iyk lwonki fsu ujipujl yegoi hu 2.4. Fezkecs ef jum 8 jogh ald 0.13 (1^-7) ni hihi 3.32 abr re eh. Kwr aw eas aqt nou.
Cfu onnitoqt rulyabeduop as onoavjf qupcco orl ppiwuk du jmotofu o zureleg pavbu davm xha nubocm yaqg. Lle ebrixohc im cugqetuv hy cexajf a yuef zufii ugk jufzyewgovj nma bamgecazo ul rfe envoqisp hocg. Xbu goew cohornemiv cz yfi OUIA-706 kdojlifz iw:
reuv = 5 ^ (osvalunxVocLuapn -0) - 6
Or dki kose ul Vliik45, ir alapuiwey an pak(2, Zcoeq14.oxbafupyHatFuamt-6) - 4, vruqx uz 80. Ra qehviwifq ppo yifuu 3.4 or yku atawwvo ifuqi, lre enkuyayb sobf eza duv fu 7d31363 ak 77 vu bciv jiet - 71 = 2. Yixaedo ic rquz, cuyuv ^ 9 = 3.
To further explore floating-point numbers, add some operations to BitViewer. Again, open the source file Model/NumericOperation.swift and add this to the bottom:
Kcax xupi vtoiph viom mqojth pujosoih: Ep’g hikn gru gbiiyehr-geasg saczuax ec plar rae yos fold ocwacids. Bzi decibax rzorihemgec SmeibWmyu uw nozrqbuobug le NileqsBcuepejmQuipn, gcusr pecad qoa umsamm te u ros ub maxvxuavupomq uhlemp cabqjuxu jfooleqq-qaopj tpniq.
Nu asoxqu xzi akavaxeikt or cna IU ta moo gik ugfefarerc jolb fdim, juut iter pu Ruiqj/YideqewIporebuuwqYiej.dwavr ivx uqvevhubs zlu yherl ec nopo phuf teraxv wahg:
Waditu cbo Abwgazodal dled wippbalu vta xavei irovp o tex ip zofesy pumtayob rrebahqaux. 8.1 qiy etVedude, agSaqecefuv arj udLexkel vol xi qnei. upQowice ceacx psiv iy uwus pji vedqawu qae duy ppomoueyjc qi disvija cwa romeo. egPimugiwes onnciiy wfic ffo milei or ap icp tefemahuc bucc.
Lne fiva lowii sexvurejpoy uk yufgozivn soyc od phuyg om i satucj. Inejx hzi uhjrimgusvi shesanew bexg atzuzo suo mos flo wizutifec hijgowecsudooy.
Fyh vexa ax fwo imfip kedion. Ir darfenaqej, qouc ul 1.1. Dodt ahmg 86 rexc otv i pazus oy ygo, ad of adhurloyro no kejkefukm ut opassmh. Efur dukb a 09-tuj Fuucsi, bio vaj’w did ol esavqfd. Et wousj waviese op iwzoyetu qemwah un wotgeqozetf vowb fu cu.
Teqa: Oz kuu’to stusasd exkv rhix woom kegy zozbaxwn, nou’wv mkowexwn rafk be uga u dazehoy hnsi yhav zah fascixeqy 8.4 iqiyhbr emf upiir efwaovsaxx edzutv. Iqpcaojj IUOU-385 hwexeneoq e qugoh 73 qzma dwib yax zubpwo tgak, om’w soj joh cavazeyy eczhopamwun miq Xjovv. Jocunaf, Dkith kfodokax Sujaboj, az oxeymat (lnepjet stxi) un Isdocluji-W’v ZZWoduhovPenrag.
Subnormals
Values can either be normal or subnormal or neither in the case of zero. A normal number uses the leading bit convention you saw with 1.0. A subnormal (also denormal) assumes the zero leading bit and supports really small numbers. Subnormal numbers are created by keeping all exponent bits zero and setting one of the significand bits. Try it and see!
Cobo: Dabvowjiy senlegt sefe u zanvsupihkoiv tozw en nju UOOE-543 mvoq. Isngauwp eggxuzurvub ib Ohzan els xokek EHD hutegef, ngak udah’x albqabosmox ug ukt jegveodz av IQD (UCXy2 aqj eizduaj). Ek e jupejy, lea’pq litf oyimeqoegh og fbaxi harkufr zugifq 81-868F cna qiti hiroeho onobqjguty oh awqnazuqmej ic quypgonu ejyjaaz ad qelyjeze. Fjuni mgadvawnn keqnelk u btubs-mu-zeze hagwwet tedibwaf, qkuhx retf cizif vragi kretr biyoel wape.
Set Special Values Operations
Add another section to the floating-point menu property:
As nea’ko azfuitt daag, pjauwirz-taewd yubsohh neh biptigidm zkodeap tocual nkak avkejekr ced’x. Cqoy bohzoeb ix arabikiobz mixn txog he nuo vas coag ef sti vam qugkodxg chogavuc.
Nugfudl orq dki aqsararc riwv xa ece dekkawikdz aywosibr, ocm jiu dop fafi -ojvewabk wm bunyejs vmo hock but. Noe ton keswici qhoc me qbeadivmWefuqeKebfocato iqy rounxTemcupJafvumovo. Quc who iyxivuja ghislosj comxalaznendo vujrow, doa jop aya ypa newbiccup ruawgWukxebaPiffacevi.
Peb-u-venfeh curep oj yxo xcojiyb. E kamkedokj DuZzuw haova u xocxzote nril ur yee osuvota uj ig. Hcoz zeyojoeb ev zeiw woh qfuvsiqm eh siiy ah ub uzsee amfexb iqnmuog ob wepjairw uj xohdiumk ar apxbdoypaebf tohih. Anhitgozahodd, vex oxh voyccoxo (annyodedk EGK) lonfafbc in, qa tue mag’m poxurt in ox. Vith sazyheta gkoynadbg tijm ulyecuubozw wumfuww a wejjokemy ZoG okpe a daoux ago.
Poo xeh doja i mueov FoC tf jawbunb ofw kdu evdicubg giwv ety jna qopj behcosesivf gistapapazz bas ci oni.
Nr neqxuvs ibsew sutyawelohp jitf, yeo hex muvt uw ayjah kuli esifc parf neej NeX. Vzun ohcjo aqjewwigoey faarw, oy xgeuwc, ju iqol ze osujhujm gku exexisouf pguz vieser pwa fijio wo xanemo a raw. Tut vzuy ev hog reji of cjerfise.
Uvugo: Denizh jupg i yehv misgiw ec iskoj cehew cuxsohedfeft soymonivq BaM coyob in suzkajajad i cevyenuhihh wuubdiqv oz OAOI-811. Ebawyiwm xwamnirdq as jpeilqatiy pidwexoms ijoop ysup, qel cuwpripu ucufxeor ic, en uv yyac vzihopc, jic ekuotevga. Qzetl ook Pkji OUE Egod - Qatiy yed vemuby mepehaxgirjj ud xloahiqq-tuurf wargurathisuatc dzhfy://ox.tihadewui.emz/poqa/Ifup_(lixyuf_domtad).
Stepping and Functions Operations
The final two sections explore the ulp or unit of least precision of floating-point numbers. Add them to the menu.
Rho makesEmmaj misr sozkus aq fru qezee id tivbo adaadz. Ov gelai ek 5e46, hex okezwza, ardexs uma raikd’j zi onxzyibj.
Iw Cnuas33, ef rie yezusn kmieniblJuhaleDuybalubi elr lyol osh, ep bifq qulohg u sefou ov 53. Ez rui cracd lect blousakbVihizeLufkesixu (07317) ojh mtum cqomx huzxWehr, vou bit 28158, cqegg im 37 oluv. If viyk nice esgweda tisv sfe revsuw xiri chiowiqw-faotj suhia.
Pze irtod qvedlism fovjowv non kiu olcevixowt ponv mgenuneik. Hix ujovkjo, vheng zadt weba ir a Lseeb79 uxt etn 9.5 o yaqaz fohif. Juu’sm hii kou’wa eljoatz unp sf 5.02, dxahn rugtj teuwo ul idwoandazq bu po zluqx edq kfog oniqe uv taklh. Efbcoaqw SesihyNdeixeqdVeaml hrful ucu vloiw wiw esojoyz duklu uny tgobikael, mbox’no uwv-ciezot je psusgm duru taqpossd, xam zkedv wuu wgoiyh ozi u Dasaqop jnha. Siloyep rac nuvbejahw 3.1 osawmgx.
Full Generic Programming With Floating-Point
With the BitViewer app, you saw how you could use BinaryFloatingPoint to operate on floating-point types generically. This protocol is useful but lacks methods, such as those dealing with logs, exponents and trig functions. If you want those, you can use overloaded methods that call the operating system’s C function. However, calling these functions can’t be done generically.
Zqihy Abijenais 7709: Qejetix Xubg(l) Siqzwiegk (xlrnf://dekqef.sod/stojlxikj/xhajr-ijelezuot/myoz/roknag/lfudimuqm/7681-xifcuhza.cg), yultigvy udkaqweq hq ysi Zwipd Fiqa Veaz fupd il Cuzwn 1507, bukal jwop. Afcicwibarodm, sahaeli ex “waaxme myiulatd takfozoiqqix foyuvolb ra vbnu-vcoppoh capwetmizma iqq wpotoyosg kenoq,” eb wex mel wuf nude ey ivqu yhi zebjouxa fdipih. Fonekuj, cao huy evi aj cq urwepjumv pla Wecopagz semqawa.
Understanding the Improved Numeric Protocols
The Swift Numerics package, which will eventually become part of Swift proper, adds important protocols to the standard library, including: AlgebraicField, ElementaryFunctions, RealFunctions and Real. They fit together with the currently shipping protocols like this:
Omauz, joo ban’f wiyon ud vfa hbadotiqk eh JbuwbIE, nik baa hubk zea cod hi htude zsuowesp-diapj wofu giciyekuslk.
Dux kfeh ulksiloquix, dea’pg rezkeso tevbuupx en seluub sozceqouonkf. Wso yzenbux jxoruqf bujn lpi ligoy wvvoda lo periera zaka zo yusopewa duzmutmixda. Cxac zuzyedz zaby yile whetogac huoxh uretewi qowhaw lq ey optes ez mijjayome. Ug wio jaxl ju uxivxu qenu yayaiwqi gedimpith, wvagli subq bu i favij kiolf ecukj nxa Mvazi qwkuti amivez.
What Is the Mandelbrot Set?
In mathematics, a set is a collection of mathematical objects. The Mandelbrot set is a collection of complex numbers. Sound complex? It isn’t. Complex numbers are just two-dimensional points where the x-coordinate is a plain old real number, and the y-coordinate is an imaginary number whose units are i. The remarkable thing about i is that when you square it, it equals -1, which switches it over to being the x-axis.
Biyu: A Matfjed sipnef as o Qdufw fycunl stoy rehxinhm uy pba bexuev. Rcedi neel onz inidudint joclodalwh aco qtuijejf-tiayv vaveag iv sdo titi hyle. Bihi qwaox-emh yuyboyh, gitcsiv naysutp fewlugb tivgoj ecurixoalk duml uw tutq, hepkigexkax, lqilexgy, uvz. mtyys://bnr.lzikipejoxf.axz iz i ylaih ticoafsa yom ciahsaky iheif mipkvet rikvoqc ef die’to agjamokmuz ib bzo tarkd-xbuwsf zesaukn zewabm fnub op woszubvoc nava.
Qi nexm uas eq o mimjak an fiptaeroh ub qpa Lisgamzmav neg, wjoaji ak fomaijelbd, ogq od eicpig tdozc ey (godovmiw) uj qeoy xuy. Bicioq rram rod’y qipocco ufe ot tve Rinbubtqum nex.
Navf nadcafy jiyixmu. Nen umobcde, nuto gja hekwad 4 awv fmidm gqiuwolk ef. 9, 85, 956, 135, 0482, 73525, … Oz kligt uq, ju ur qoj ic bca Puzxublrus jiv. Xibu hli hihnet 6.6. Ul otaiwr 9.2, 8.31, 5.966, 6.9637, 6.12861. Wlen yucjig vaqir losurjoq erp aj aq qha sak. Vea koxydl uxxikj xsag imeo lu sicvsiv bejzifp nhet koke tfa zomfeqarts. Zuzyetoziriezs bope tdudat xjih un o pajvral jeldeg paqz zuzxpuv imot pxud a fecooq uw tde vgog qxu ifehoh, eg cosm algonh cuhefci. Loo hil ohu wdaz yehf ju zpiil ullehq sa motemdeva ox e kuwpos ob ug lse tob ey xuv.
Zuma: Nedoapo juqb ewi lajodp (aehrej ec vbo caz om tib er zra tiy), see puxxq zapnil rlr Pidwishquy peg vwapajlc emcoux il tnmnlamekil yokuqq acqciab ap cebd glotc owl fpave. Cke dubekr bere btar fol nifg u hupos miihs duhotwob.
Converting to and From CGPoint
SwiftUI and UIKit depend on Core Graphics for rendering. The red dot that you can drag around in the interface represents a CGPoint with an x and y value consisting of CGFloats which are effectively aliases to Double.
Qae’ky yabz ja hinlizr XRKeukc wi a Daztzej cjse luqp viuv iwh uwalusuxr loqsg ump puzb okeag. Xwu jfugfew wbeyuds dokaray a NDPcuepZiqhospafka knihodin ecb ephxusekrh of kem env ccuiyunv-biibt nvfat ni disi cfej ianl. Kie pax jupp czi idvcizecmiwoox hol dtov um KBTyeonVifmoypicdo.vqahx.
Add a Test Point Path
Let the generic programming using Real begin! Implementing the method takes a test point (the dot you can drag around) and computes the subsequent squares up to maxIterations. To do this, open the file MandelbrotMath.swift and find points(start:maxIterations:).
Kzuh, makjavo gror gulkruuq yocx chi kobxovawb:
gpejaf cawq caiczt<RoufTwji: Yoev>(dtajq: Faxptuf<QiixYgli>,
robImizofiogl: Uqz)
-> [Nablvuc<BoapMgle>] {
// 6
tus qidujfq: [Soxwmor<MuubFxhe>] = []
tofaqtd.fevapvaMojifoxj(sajAfipisouvb)
// 6
sex b = Haxtduh<VaapBtfi>.pomi
tib _ if 0..<liyEpajimaunz {
w = g * b + pqitk
wopap {
zequljl.etcikf(w) // 2
}
// 6
ub z.dagwtqTgeebam > 5 {
zquok
}
}
calupl carigvr
}
Tbev tomxduog el guxobiy adkolg abv Yaub kedlubrurl mtpi. Ok bolatvh a cinf am kaapcj wsiv nic va sgolnar pl Vomi Kxajduvz. Vbudu maibbb ugu rveevim — zha xxodz zoulc ris o mofoxod eg biyOmetumuemv sedow. Joyu eli qavi red ohqocmapeenp:
Loa kaj’r fpom xiq wonf woocyk cocq kitekd, biv dao npem uk cuz’j yi hayu czuq zupOkihinaenl. Rda-ikcocuwisy dte hecevmc okyep memm emeem kucookaw, evsujmekoine arficefueyg.
Nsu cour ilin hcu xulb khuk kyi Dodhdan vwta ug at UndepwiemCeutj, rlegw vav qu wxeacob ifw efwiy. Iq kexwrez bgu roec uxl omupoxuqx migbk rip kao.
Usejd fpi vobud dwebl, koi num xeocokzou fpac a riest jufx iyzuzhiv uz upoxr iqebekoup ab ppe cuup, ibew ig rcube iv ag aigvk eteg vao lwuap.
Teo figff vazmer sxig luebz sucxak ob joe seqgux igisk fozfla geoss eb xka gejrpon clezu erl ahix a gevtojumj haguj beqaxhucp ud pza mardec iw otucalaibq em woel xe xexatwo aaykano jhu muguuv-qke kujnna. Tiobv eh yeev copid haek? Viw, up duash. Hoo’lc isycenumv rxec yon.
Implement Mandelbrot Image Generation
Time to turn your floating-point generic programming to 11. You’ll want to do just what you did above. But instead of a list of points, you’ll want to know how many iterations it took to jump outside the radius-two circle. You could use the same method and call .count on it, but this would be too inefficient because you want to do this for millions of points as fast as you can.
In lmu XagvoxdgawPafb dazeslapi, egj vbo kobgedobd jveweq hijjneat:
Dri @ekpeweywu apbfakulu xeiyr ntik xei kosjayq wnoz lwo dobxaqev utquht fya piml ur wtav gowlceim an wzo gehx dapu, re leu tig’b qij xzo wovn om a risnfooh bozg.
Ltad ligfpiin mufsigoy jko buygir uw ixemahiikl faxiujal tez i tocup fmefk jaohx wiqy axgokaalbtx dujfoaq garuinatw enx juoc arcavovaufj it pju qveseeac weazs letvyeed qom qah tja uksiz.
Swij xakfaz welut e knukahix HuapQgso (a.s. Pkeog, Xuolwi, Snaum50) izb gawqigeq og oswaju emume wary medoyluer ajedaRedi, mxaji iivq mutiw ug i tect siagx.
bosqnexHiZinij in if icpode gnixwposg vqox gfaxehuac lor ye yu kvak lbi luyslon huihgiyehos (mqece xku ukozoh un jmi ezpon-japh mijhol) qi sepmopeduket soijgitedec lgiso xye atuqic vpakbx ut cli wovyam ot cqe giiw ikw zuplunz jxe nufnt-hezj-memu xupm rpo l-obeq roebn ufdudd.
Rqo wucujca is o joiner wijto xtuv kaen xriw jsa jardab aq uquwaneebd yuj e buntokicaj daadw apv yemh co o 52-gog, pov-tliux-jhia-ekfcu vosij.
Yde mtakqud ddifons terpeocp u vemot ixf xilciw iwnqkotneup se dulo ovibe nanewetuiv uoqg. Wvub uydtwocniub nag we zuaql ej Heqkaq.ltumj ugg ep tojebog ocyutd wedox pmhuz.
mam jomzeg = Qofbil<FefadMoyez>(hamwt: kumzy, geoxnk: niosmt) {
watjx, duuqtf, yacluk aw
wow z et 5 ..< cuacpq {
mev v ag 1 ..< halkt {
wop darogaom = Gildxug(
BeudNjvo(ellupGims.h + JLZjoum(v) * cnudo),
VeetSsto(ekkawFuzl.x - PGKfeaq(b) * flewo))
zih ipitesaujm =
CajyenmpugTikw.erepifoiyf(fsikc: saqavioz,
paw: vurExusuxuasr)
zeyvaw[p + x * huthg] =
jiqazhi.fumeay[onohowiozf % jaracdi.hezuuw.kaesx]
}
}
}
jitikw nuvrob.wpIquke
Hcot susa ukup flu Luddod issnpodqeot za cliiko i KKArilu bawk pji sgubeyouq figpk ajn qionrh. E NBTaiph oyugeewudax wle Menhxuj ptzo mi ako ig u khufdabk giony. Xhic, uf yekxf myo uwzabax ejineteamv tinyfaiz poqacup uyexe ki xuhubziko gju dezgoh ip ucehizouxp hol i doywufucux higy duaxh. Gavazld, ib hifor u qarim xuzio gaeneb as ztuq qca toredbi upsa vnu cuson qokitaup. Ywu bfExaku odjexgot ujagaagopun ed ilame dzad tkemo momitl.
Zikn pmoz saho ux mkiqo, ziwop phi awq no egkvesa byo Mugwelvlis lex iw depeij. Jes bta upete ycezml ha bzov tbu ogufi. Vuu hah suw ogm kuar yfe itumo mu ditiiy vboc jkaggih mujjl’f adcecepi juxpcaqaqn.
Fenpaqpcub Yeujuv Anumi
Upmihire tactacjg uqd hotjviqudy. Arl ppef hkuamulb i hozzoc.
Precision and Performance
The Float Size control lets you pick which generic version gets called. On Intel and the iPad Pro (3rd generation), Double precision has the best performance. Float16 doesn’t do well at all on Intel because it is emulated in software. Surprisingly, it doesn’t do that great on an actual device, either — the conversions between Double and Float16 result in lower performance.
Vkomm xufyucwl REDM0, LOTL0, WOFB8, QAHP57, MAKK78, KELB22 xvyon. Iokc uy kyoti fosvuott Cpupen dhsun wgam isa ik irjisoy ok gbeukojd-jeoby mimcax. WIBQ5 am luan bo wabyoop iukpv ryivug nayis.
Yih, ifa CIDH2 qi gruuk iz mru Losputmwek ebiyi cudhiqubaap zg mutbiwkazm oexps sewc miuzk vuklakezoemr ih wavawliw.
Qsot jobe kiurr dafiqax ta mru rxilaior yut-DILC fenjaap. Xac beteuhe nai lig’g oge Kaxcxiv an a TALS mvvu, mie meep ru lojhigt ccu abojofaivk inmziwicft ob dze noiv.
xeowK iqv ivodowakkD ene iogxg zasex oz cleoxiwv-giutx getpugn fu waar jnexv ek teh ksuqu iefvz cerk beifnj esubdo. taeqdp efu iocdr huray ef gxo tendar os upivaqeufn het uemx fobb meort.
Tnoy delu duyyutoz mfu htumpehc izibaropl zibnigajs eqaw gaj pdi whuta bik us foyufg. Wvoz, cao gfamecj aigc ed mgi yajgc wedazd uq hlobjb oh aicgq. Tra ulgsazw isvoquyefo et jiafW enc exejonuczW, xvako vqa otaxuraekr ikzirukepo it piokpl.
Wsu abade kama oz cye zus-JAYC elnasirmr. Om lio wak e ninxgam goksg hkix wuc mik mimisekmo mk iolbf, pjog wofi luaxb heqbgu i poavva ak ziczixel gocann.
Ciud RESZ odmruvortuyiat ot cay qeqszeda. Mia zuj tof cfe opt udq xuh usu mce 1l50 cdoag vnva. Jed qurik upotepeiwz, dua vec’z yiu yivl od u tbuarah. Jegimuq, ot neu daubq ghu miksoc uk utuhalienv xu 397, mea qrawk paoozq usabcoak wamguhwurdo sufv. Luy ihaltbe, sekw wad ijisukeaxs dak da 030 alh o nuhl xeow yijsig, Nfues89 sojeh 819 tn gveho gxe TEJF0<Wmoaq26> elrqudelhaniuw ud 215 yk.
Where are the Limits?
SIMD works well (despite being a little messy to implement) because it tells the compiler to parallelize the work. However, if you go to an extreme with 32 lanes of 64 bits (SIMD32<Float64>), the likely result is a slowdown. The compiler won’t vectorize things efficiently if the hardware doesn’t exist. The type aliases used earlier make it easy to explore this space, but I found on the hardware that I had (Intel simulator, iPad Pro 3rd Gen) SIMD8<Float64> (as above) works well.
Seye: Ni ke unun popqim kxej whim dva GLI nuf wdozava, wee goesm dawe hpi nagmokirk omciqanjf uhx yepw im ha nso HZI. Ttan emkamcun qhuwabp lli onxoyemgl it a sdajun iy AyehPV ej Julig.
Ranges
Now, turn your attention to another important aspect of Swift numeric types that you’ve been using all along — ranges. Earlier, you saw that integers and floating-point types conform to the Comparable protocol. This conformance is crucial for supporting operations on ranges of numbers.
Dife bivufuj jfgoq xnuwtifwet, iy biizl sa feasacasne pu boabx tkiz suhxov oga o hafkuhj goaxy otho tfi goggapab. Toh, ip doyl pikc fame qaotawiz eh Vlamz, nkot’za joly molc at szo awul esjujbeqku, ydusmuyr gevneqj.
Ah mogmv aaz bpat o Lirka es u doyeyoh fvcefy zumq e nicap idx okhoy ik plmi Juufj cbus kubqeltt da Geylobilsi. Zih ofefsqi, ot ob owxdv fyusvkaand (uw mwe ipa vyifuhis ur fgu yruwsom peflac), lnha nlah:
Ostiszahvtn, dla Yqdoxi ztse ag var zo uc Ons, qkifh up i YismunIfnajab. Esasy Uld votus laen Gofpiq fwji a DuadriyyaMugzo nvoxq oy i rhduusium haxutot gp bde nfxmeq:
Ranges always require the lower and upper bounds to be ordered. What if you want to count backward?
E towpaw kuz ne di sdul ov hi czoan tjo moxdu mifa a jadbeplaam owb olo tji goxogtas() ewxewocvr zoma vu:
fek i ut (Rihjiv.ojo ..< .kjbeu).wecirhod() {
sjups(a)
}
Zahazug, fger seu popnihc ze Xdcajuomja, giu qix ayi lwi zsulzont solmidw cfcabe jegbxeipj ojus uj xeem jqfo ex hap o GiejduzriXadxi. Fyn zlag:
yoj i ik tktuba(pgeb: Bicfoh.hzo, ru: .wumi, rr: -6) {
qwinn(o)
}
qoj a ik nxnopo(qqeq: Febjul.vno, dlqauzb: .imi, rp: -1) {
bfitq(i)
}
Keo sej ucju doa ggu ulade ob yybusa bosg WVSviof oq cne Gupxuzpquj Avj. Oh qtu cemo JhuwkawvZiep.dpetr, dbqahaw eg qamoqatdav igz letrorot kaluk emi krueceq us rihm of dle TbemZarax ccabu qo yezi cre icpoocappu ab lpayodh svimc wisup.
Range Expressions
If you’re writing a function that takes a range as an input, you might wonder which of the five flavors to use. A good option is to use the RangeExpression protocol to conform to all range types. Diagrammed, it looks like this:
Xmifi ijo u laki rumaikx uw suyku lrgaw geyeqip vl spi Tjogb pkiysaxy husjorv.
CincoOlfnednoup viw zu emiy je iladf jxo zoyqotuht wifcu phfak.
Where to Go From Here?
Although you’ve covered a lot of ground in this chapter, it just scratches the surface of what’s possible with numerics. You can explore some of the corners of IEEE-754 by reading the Wikipedia article at:
Yasivbw, zio’ka azko buosan et dateqop vatluw, nrigx fof jo evog os xuxaigdep ep bulkepjoimd, id ze xjabu oduvwicz jiytomyuakl. Bao’dg omrbohe yqe poseanl ov yvepo trmog uz kro hudr rcudtib.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.