kompastuin tähän SO-kysymykseen , joka kysyi tapaa muuntaa suuremmat heksadesimaaliarvot positiiviseksi numeeriseksi arvoksi:

?Val("&H8000") -32768 Val("&HFFFF") -1 

Vastaukseni sisälsi merkkijonon numeroiden iteroinnin yksitellen ja niiden arvon laskemisen tulokseen:

Function ConvertHex(ByVal value As String) As Double If Left(value, 2) = "&H" Then value = Right(value, Len(value) - 2) End If Dim result As Double Dim i As Integer, j As Integer For i = Len(value) To 1 Step -1 Dim digit As String digit = Mid$(value, i, 1) result = result + (16 ^ j) * Val("&H" & digit) j = j + 1 Next ConvertHex = result End Function 

Se toimii, mutta osaan ” Ei auta ajattelemassa, että olen tehnyt jotain typerästi liian monimutkaista jollekin, jonka pitäisi olla melko yksinkertaista.

Onko parempi tapa, etkö ole?

Kommentit

  • Olen ' hämmentynyt siitä, mitä haluat saavuttaa. " Kaksinkertainen " tarkoittaa yleensä 64-bittistä liukuluvun numeroa. Silti tekstissä sanotaan, että haluat " positiivisen numeerisen arvon ", mutta silloin esimerkkisi näyttävät näyttävän allekirjoitettuja 16-bittiset kokonaisluvut (kutsutaan yleensä " lyhyeksi "). Lisäksi näyttää siltä, että vain kokonaislukuja voidaan mahdollisesti edustaa heksadesimaalisessa merkkijonossa, joten palautustyypin tulisi olla Short, Integer, Long, UShort, UInteger, ULong tai Decimal.
  • @ 200_success Siellä ' on vain hyvin rajoitettu joukko tietotyypit VBA: ssa. Ei allekirjoittamattomia tyyppejä …
  • Mat, mitä ' vikaa Cdbl("&HFFFF")?
  • @Joskus näen vastaukseni päivityksen, miksi CDbl on mielestäni väärä tässä tilanteessa.
  • @Taidossa se on täsmälleen mitä tarkoitin sanalla " Olen ' tehnyt jotain typerästi liian monimutkaista jollekin, jonka pitäisi olla melko yksinkertaista " 😉

Vastaa

Mistä voin kertoa merkkijonon, joka alkaa &H on kuusikulmion kirjain.

on useita muunnosfunktioita , jotka voivat muuntaa lausekkeen haluttuun tyyppiin.

Joten sen pitäisi yksinkertaisesti olla, riippuen halutusta tyypistä:

Function ConvertHex(ByVal value As String) As Currency Dim result As Currency result = CCur(value) If result < 0 Then "Add two times Int32.MaxValue and another 2 for the overflow "Because the hex value is apparently parsed as a signed Int64/Int32 result = result + &H7FFFFFFF + &H7FFFFFFF + 2 End If ConvertHex = result End Function 

Valuutta vs. kaksinkertainen

Suurin tarkasti esitettävä positiivinen kokonaislukuarvo:

Miksi siis käyttää Currency yli Double, kun jälkimmäinen toimii suuremmalla kokonaislukualueella?

Currency on aina tarkka. Jos ylitämme Currency -arvon, saat virheilmoituksen. Jos ylitämme kaksinkertaisen suurimman edustettavan kokonaisluvun arvon, saadaan likimääräinen kokonaislukuarvo:

Dim doubleMax As Double Dim doubleAfter As Double doubleMax = CDbl("&H0020000000000000") doubleAfter = doubleMax + 1 MsgBox "Double before: " & Format(doubleMax, "#") & vbNewLine & "after: " & Format(doubleAfter, "#") Dim currencyMax As Currency Dim currencyAfter As Currency currencyMax = CCur("&H000346DC5D638865") currencyAfter = currencyMax + 1 MsgBox "Currency before: " & Format(currencyMax, "#") & vbNewLine & "after: " & Format(currencyAfter, "#") 

Tämän esimerkin tulos on:

 Double before: 9007199254740990 after: 9007199254740990  

Ja sitten run-time error "6": Overflow, joka on hieno, jos haluat välttää pyöristysvirheet. Nyt MSDN väittää, että Double on

tallennettu IEEE 64-bittisenä (8-tavuisena) liukuluvunumerona

mutta jos olet lukenut jotain IEEE 754 -binaarisesta 64 , sinun pitäisi olla hieman yllättynyt esimerkin tuloksesta. Todellinen enimmäismäärä on &H00038D7EA4C68000 (1 000 000 000 000 000).

Kommentit

  • Mahtavaa! Olen ' linkittänyt tämän vastauksen SO-vastaukseni muokkauksessa 🙂
  • Laajensin bitin aiheesta Currency vs Double vähän ja löysi jotain mielenkiintoista.
  • Entä doubleMax + doubleMax heittää ylivuotovirhe?
  • @Meinäesti vain testasin sen ja ilmeisesti VBA: n Double ylivuoto. Mutta se ' on edelleen ei ole mahdollista ylivuotoa, jos jäsennetty tulos on kokonaisluku. I ' iloinen, että en ' ei tarvitse työskennellä kyseisen kielen kanssa.
  • Oikea, idiomaattinen tapa tehdä tämä on käyttää yhtä sisäänrakennetuista muunnosfunktioista, kuten @Me jotenkin kommentoi OP: ta – En tiedä ' en tiedä mikä aivoriihi sai minut jopa kirjoittamaan tämän toiminnon …

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *