JavaScript'te ondalık sayı onaltılık biçime nasıl dönüştürülür


1479

JavaScript'te ondalık değerleri onaltılık eşdeğerlerine nasıl dönüştürürsünüz?


7
Burada bir uyarı, bir dize gösteriminden başlayarak, hex'e dönüştürmenin bir parçası olarak Number'a dönüştürdüğünüzde kesinlik kaybetmek çok kolaydır. Bkz. Danvk.org/wp/2012-01-20/… .
studgeek

Bu işlev tam olarak ihtiyacınız olan şey
Mohammad Musavi

Yanıtlar:


2474

Bir sayıyı onaltılık bir dizeye şu şekilde dönüştürün:

hexString = yourNumber.toString(16);

Ve süreci tersine çevir:

yourNumber = parseInt(hexString, 16);

42
yourNum bu durumda onaltılık bir dizedir. Örneğin (255) .toString (16) == 'ff' && parseInt ('ff', 16) == 255
Prestaul

8
@forste, bir javascript Numarası (ECMA komut dosyasında bir Double olan bir Number nesnesi) hex ve geri bu tekniği kullanarak dönüştürürseniz "gevşek" olmaz. Bağladığınız soru, özellikle bir Double'e sığmayacak kadar büyük sayılara atıfta bulunmaktır (bu nedenle sorudaki dize temsili). Bir Numaranız varsa, bu işe yarayacaktır. Javascript Number nesnesi (Double) olamayacak kadar büyük bir şeyiniz varsa, başka bir şey bulmanız gerekir.
Mart'ta Prestaul

12
@Derek, gereksiz parantezleri tolere etmeme izin vermeyen psikolojik bir sorunum var ... @ herkes-başka yourNumberbir değişkendir. Sayısal bir değişmez değer kullanmak istiyorsanız, o zaman böyle bir şey yapmanız gerekir (45).toString(16), ancak bir sayıyı zor kodluyorsanız, lütfen onu bir onaltılık dize olarak yazınız ... (45).toString(16)her zaman eşit olacaktır '2d', bu yüzden cpu israf etmeyin anlamaya döngüleri.
Prestaul

21
@Prestaul "Bunu anlamak için cpu döngülerini boşa harcamayın" - buna erken optimizasyon denir. JavaScript 286'da çalışmadığı sürece, genel giderlerden şüpheliyim. Ayrıca, '45', programcının tanıması gereken sihirli bir sayı olabilir (saniyeler içinde zaman aşımı süresi gibi), '2d' ise bunu kim tanıyacak?
Dejay Clayton

47
Parantezlerden hoşlanmıyorsanız, fazladan bir nokta kullanabilirsiniz:42..toString(16)
Thomas Watson

142

Bit alanları veya 32 bit renkler gibi şeyleri işlemeniz gerekiyorsa, imzalı sayılarla uğraşmanız gerekir. JavaScript işlevi toString(16), genellikle istediğiniz gibi olmayan negatif bir onaltılık sayı döndürür. Bu işlev, pozitif bir sayı yapmak için çılgın bir ekleme yapar.

function decimalToHexString(number)
{
  if (number < 0)
  {
    number = 0xFFFFFFFF + number + 1;
  }

  return number.toString(16).toUpperCase();
}

console.log(decimalToHexString(27));
console.log(decimalToHexString(48.6));


5
bu ikisinin tamamlayıcısı mı?
Julian

2
JavaScript, 32 bitlik tüm alanları imzasız sayılar olarak gösterebileceğinden, normalde bu dönüştürmeye gerek yoktur (Bkz. Number.MAX_SAFE_INTEGER). Aynı nedenden ötürü imzasız hale number = 0x100000000 + number;
getirme

3
Önceki yorumumla ilgili kısa bir not: Hex temsili Number.MAX_SAFE_INTEGER'e kadar olan sayılar için çalışsa da, bu bitsel işlemler için geçerli değildir (genellikle 32 bit renkler oluşturmak için kullanılır). Bitsel işlemlerin sonucu her zaman işaretli bir 32 bit tam sayıdır. Bu nedenle bitsel sonuçlar> = 2 ^ 31 negatiftir ve 0x100000000 | 0 === 0.
Johannes Matokic

25
>>>Numarayı imzasız temsile dönüştürmek için operatörü kullanabilirsiniz ; örneğin, ((-3253) >>> 0).toString(16)döndürür "fffff34b".
csharpfolk

1
+1yararlı bir ekleme için, ancak sayıları farklı bir gösterime dönüştürüyorsanız, tüm sayılar zaten "genellikle" pozitiftir, aksi takdirde negatif sonuçlar almak istersiniz.
Carl Smith

82

Aşağıdaki kod d ondalık değerini onaltılık biçime dönüştürecektir. Ayrıca onaltılık sonuca dolgu ekleyebilmenizi sağlar. Böylece 0 varsayılan olarak 00 olur.

function decimalToHex(d, padding) {
    var hex = Number(d).toString(16);
    padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;

    while (hex.length < padding) {
        hex = "0" + hex;
    }

    return hex;
}

5
Bu negatif değerleri düzgün işlemez. decimalToHex (-6, 4) 00-6 değerini döndürür.
JonMR

3
Ayrıca kayan noktalarla ilgili sorunları var, ancak Math.round () 'a koymak bunu düzeltti. (+ 1ed)
Michael - Clay Shirky

Bir diziden ('255,0,55', vb.) Sayıları "çekiyorum" ve .toString (16) işe yaramadı. Tüm sahip olduğum aynı sayılardı! Öne "Sayı" işlevini ekledim ve şimdi çalışıyor! Sadece çözüm bulmaya çalışırken yaklaşık dört saat geçirdim!
Cristofayre

65
function toHex(d) {
    return  ("0"+(Number(d).toString(16))).slice(-2).toUpperCase()
}

1
function hexRep(number, width) { return (number+Math.pow(16, precision)).toString(16).slice(-width); }
Lori

2
Bunu genişletmek o kadar zor değil, son rakamları orada .slice (-number) ile dilimliyorsunuz. Cepheye daha fazla sıfır eklerseniz iyi çalışır.
17'de

19
ES6 const hex = d => Number(d).toString(16).padStart(2, '0')😁
Ninh Pham

39

İstersen tamlığı için two's-tamamlayıcı Negatif bir sayının onaltılık gösterimini, kullanabileceğiniz sıfır doldurma sağ kaydırma >>>operatörü . Örneğin:

> (-1).toString(16)
"-1"

> ((-2)>>>0).toString(16)
"fffffffe"

Ancak bir sınırlama vardır: JavaScript bitsel operatörleri işlenenlerini 32 bitlik bir dizi olarak ele alır , yani 32 bitlik ikinin tamamlayıcısını alırsınız.


2
Bu, bu sorunun açık ara en değerli cevabıdır :)
albertjan

Çünkü tüm soruları incelemek C# number to hexadecimalfarklı sonuçlar üretiyordu Javascript number to hexadecimal. Javascript negatif sayılarla ilgili bir sorun var gibi görünüyor. Bu cevap sorunun çözümü gibi görünüyor.
19:13 de goamn

Bu çok yardımcı oldu, teşekkürler! RGB renkler için bunu kullanıyordum, bu yüzden ilk iki karakterin (ekstra FF) 24 bit varyantını elde etmek için -((-2)>>>0).toString(16).substring(2)
antonyh

36

Dolgu ile:

function dec2hex(i) {
   return (i+0x10000).toString(16).substr(-4).toUpperCase();
}

2
@Lucas Son 4 karakteri döndürür.
Gabriel

19

Döngü olmadan:

function decimalToHex(d) {
  var hex = Number(d).toString(16);
  hex = "000000".substr(0, 6 - hex.length) + hex;
  return hex;
}

// Or "#000000".substr(0, 7 - hex.length) + hex;
// Or whatever
// *Thanks to MSDN

Ayrıca değerlendirilmesi gereken döngü testlerini kullanmamak daha iyi değil mi?

Örneğin:

for (var i = 0; i < hex.length; i++){}

Sahip olmak

for (var i = 0, var j = hex.length; i < j; i++){}

19

RGB-değer-onaltılı işlevi için bu iyi fikirlerden bazılarını birleştirmek ( #HTML / CSS için başka bir yere ekleyin ):

function rgb2hex(r,g,b) {
    if (g !== undefined)
        return Number(0x1000000 + r*0x10000 + g*0x100 + b).toString(16).substring(1);
    else
        return Number(0x1000000 + r[0]*0x10000 + r[1]*0x100 + r[2]).toString(16).substring(1);
}

Bunun için teşekkürler! Uzun zaman önce bir yorum bırakmaktan bahsediyorum. Cevabımın anahtarı buydu. stackoverflow.com/questions/5560248/…
Pimp Trizkit

16

Kabul edilen cevap, tek haneli döndürülen onaltılık kodları hesaba katmadı. Bu kolayca ayarlanabilir:

function numHex(s)
{
    var a = s.toString(16);
    if ((a.length % 2) > 0) {
        a = "0" + a;
    }
    return a;
}

ve

function strHex(s)
{
    var a = "";
    for (var i=0; i<s.length; i++) {
        a = a + numHex(s.charCodeAt(i));
    }

    return a;
}

Yukarıdaki yanıtların başkaları tarafından şu ya da bu şekilde birçok kez gönderildiğine inanıyorum. Ben böyle bir toHex () işlevinde bu sarın:

function toHex(s)
{
    var re = new RegExp(/^\s*(\+|-)?((\d+(\.\d+)?)|(\.\d+))\s*$/);

    if (re.test(s)) {
        return '#' + strHex( s.toString());
    }
    else {
        return 'A' + strHex(s);
    }
}

Sayısal normal ifadenin , web uygulamalarınızın verimliliğini artırmak için 10+ Faydalı JavaScript Düzenli İfade İşlevinden geldiğini unutmayın .

Güncelleme: Bu şeyi birkaç kez test ettikten sonra bir hata buldum (RegExp'te çift tırnak), bu yüzden bunu düzelttim. ANCAK! Biraz test ettikten ve almaz tarafından yazıyı okuduktan sonra - işe negatif sayı alamadığımı fark ettim.

Ayrıca - Bu konuda biraz okuma yaptım ve ne olursa olsun tüm JavaScript numaraları 64 bit kelime olarak saklandığından - 64 bit kelime almak için numHex kodunu değiştirmeye çalıştım. Ama bunu yapamayacağınız ortaya çıkıyor. Bir değişkene "3.14159265" NUMARA OLARAK koyarsanız, elde edebileceğiniz tek şey "3" olur, çünkü kesirli bölüme yalnızca sayı ile tekrar (IE: 10.0) çarpılarak erişilebilir. Ya da başka bir yolla - 0xF'nin onaltılık değeri, kayan nokta değerinin ANDed değerinden önce bir tamsayıya çevrilmesine neden olur ve bu da dönemin arkasındaki her şeyi kaldırır. Değeri bir bütün olarak almak yerine (yani: 3.14159265) ve AND kayan nokta değerini 0xF değerine göre yapmak.

Bu durumda yapılacak en iyi şey, 3.14159265'i bir dizeye dönüştürmek ve sonra sadece dizeyi dönüştürmektir. Yukarıdakiler nedeniyle, negatif sayıları dönüştürmeyi de kolaylaştırır, çünkü eksi işareti değerin önündeki 0x26 olur.

Yaptığım şey, değişkenin bir sayı içerdiğini belirlemekti - sadece bir dizeye dönüştürmek ve dizeyi dönüştürmek. Bu, sunucu tarafında gelen dizginin hizasını kaldırmanız ve ardından gelen bilginin sayısal olduğunu belirlemek için ihtiyaç duyacağınız herkes için anlamına gelir. Bunu, sayıların önüne "#" ve geri gelen bir karakter dizesinin önüne "A" ekleyerek kolayca yapabilirsiniz. ToHex () işlevine bakın.

İyi eğlenceler!

Başka bir yıl ve çok fazla düşünmeden sonra, "toHex" fonksiyonunun (ve ayrıca bir "fromHex" fonksiyonum var) gerçekten yenilenmesi gerektiğine karar verdim. Bütün soru "Bunu nasıl daha verimli bir şekilde yapabilirim?" Ben bir / onaltılı işlev bir şey kesirli bir parçası olup olmadığını umurumda değil ama aynı zamanda kesirli parçaların dizeye dahil olmasını sağlamak gerekir karar verdi.

Sonra soru "Onaltılık bir dizgeyle çalıştığını nereden biliyorsun?" Oldu. Cevap basit. Dünya genelinde zaten tanınan standart ön dize bilgilerini kullanın.

Başka bir deyişle - "0x" kullanın. Şimdi benim toHex fonksiyonu zaten orada olup olmadığını görmek için görünüyor ve eğer - sadece kendisine gönderilen dize döndürür. Aksi takdirde, dize, sayı, her neyse dönüştürür. Revize edilmiş toHex işlevi şöyledir:

/////////////////////////////////////////////////////////////////////////////
//  toHex().  Convert an ASCII string to hexadecimal.
/////////////////////////////////////////////////////////////////////////////
toHex(s)
{
    if (s.substr(0,2).toLowerCase() == "0x") {
        return s;
    }

    var l = "0123456789ABCDEF";
    var o = "";

    if (typeof s != "string") {
        s = s.toString();
    }
    for (var i=0; i<s.length; i++) {
        var c = s.charCodeAt(i);

        o = o + l.substr((c>>4),1) + l.substr((c & 0x0f),1);
    }

    return "0x" + o;
}

Bu, tek basamakları, kayan nokta sayılarını hesaba katan ve hatta kişinin tekrar altılı olarak onaltılık bir değer gönderip göndermediğini kontrol eden çok hızlı bir işlevdir. Yalnızca dört işlev çağrısı kullanır ve bunlardan yalnızca ikisi döngüdedir. Kullandığınız değerlerin altını kaldırmak için:

/////////////////////////////////////////////////////////////////////////////
//  fromHex().  Convert a hex string to ASCII text.
/////////////////////////////////////////////////////////////////////////////
fromHex(s)
{
    var start = 0;
    var o = "";

    if (s.substr(0,2).toLowerCase() == "0x") {
        start = 2;
    }

    if (typeof s != "string") {
        s = s.toString();
    }
    for (var i=start; i<s.length; i+=2) {
        var c = s.substr(i, 2);

        o = o + String.fromCharCode(parseInt(c, 16));
    }

    return o;
}

ToHex () işlevi gibi, fromHex () işlevi önce "0x" değerini arar ve sonra zaten bir dize değilse gelen bilgileri bir dizeye dönüştürür. Nasıl bir dize olmaz bilmiyorum - ama her ihtimale karşı - kontrol ediyorum. Daha sonra işlev iki karakter yakalar ve bunları ASCII karakterlerine çevirir. Unicode'u çevirmesini istiyorsanız, döngüyü bir seferde dört (4) karakter olacak şekilde değiştirmeniz gerekir. Ama sonra dizenin dörte bölünemediğinden emin olmanız gerekir. Öyleyse - o zaman standart bir onaltılık dizedir. (Dizenin önünde "0x" olduğunu unutmayın.)

Bir dizeye dönüştürüldüğünde -3.14159265'in hala -3.14159265 olduğunu gösteren basit bir test komut dosyası.

<?php

    echo <<<EOD
<html>
    <head><title>Test</title>
        <script>
            var a = -3.14159265;
            alert( "A = " + a );
            var b = a.toString();
            alert( "B = " + b );
        </script>
    </head>
    <body>
    </body>
</html>
EOD;

?>

JavaScript'in toString () işleviyle ilgili olarak nasıl çalıştığı nedeniyle, daha önce sorunlara neden olan tüm bu sorunlar ortadan kaldırılabilir. Artık tüm dizeler ve sayılar kolayca dönüştürülebilir. Ayrıca, nesneler gibi şeyler JavaScript'in kendisi tarafından bir hata oluşturulmasına neden olur. Bunun olabildiğince iyi olduğuna inanıyorum. Geriye kalan tek gelişme, W3C'nin JavaScript'te sadece bir toHex () ve fromHex () işlevini içermesidir.


Sanırım burada hâlâ yapacak işin var ... daha if( s.substr(0,2)önce if (typeof s != "string")istediğin gibi değil mesela. Ne dönmüştü ben (her iki beklediğim değildi toHex(0x1f635)verir "0x313238353635"). Daha fazla araştırma yapmadım.
ruffin

Yanlış olduğuna inanıyorum. Örneğin, bir dize DEĞİL - bir sayı olan onaltılı bir dize kullanıyor. Bu nedenle 1f635 olduğu gibi çıkacaktır. Eğer "0x1f635" koymak olsaydı, farklı çıkardı. (yani: rutin, rutine gönderdiğiniz onaltılı sayıyı yeni döndürürdü.) :-)
Mark Manning

İlk nokta, bir dizgide substr& kullanamayacağınızdı toLowerCase... bu yüzden ya typeofdaha erken gelmesi gerekiyor ya da eğer toHexorada dizgisiz bir yere atmayı bekliyorsanız , typeofkontrolü tamamen kaldırmalısınız . Mantıklı olmak? Yani, kodu burada düzenlemeler olmadan kullandıysam ve çağırdım toHex(0x1f635), alacağım Uncaught TypeError: s.substr is not a function. Eğer dizgeyi daha önce yayınlarsam, haklısın, sayı ilk önce ondalık sayıya döner ve işler yanlara gider. Tabii ki s, bir dize değilse burada basit bir döküm yapamazsınız.
17'de

Aslında, XP altında bu iyi çalışıyor. Javascript'in daktilo olmasını sağlayan bir dizi güncelleme yapıldı. Bu bir istisna oluşturur. XP altında jusr çalışır. En azından benim için. Tipik bir dünyada - "if (typeof s ==" string "&& s.substr (0,2) ==" 0x ") {return s;}" koymak uygundur. Ancak ox1f635 hala bir dize değildir. :-)
Mark Manning

12
var number = 3200;
var hexString = number.toString(16);

16 sayı tabanıdır ve onaltılı sayıda 16 değer vardır :-)


12

İlgilenen herkes için, bu soruya verilen cevapların çoğunu karşılaştıran bir JSFiddle .

Ve işte şu şekilde devam ettim:

function decToHex(dec) {
  return (dec + Math.pow(16, 6)).toString(16).substr(-6)
}

Ayrıca, renk veri türü olarak CSS'de kullanmak için ondalıktan onaltılıya dönüştürmek istiyorsanız, RGB değerlerini ondalıktan ayıklamayı ve rgb () kullanmayı tercih edebilirsiniz .

Örneğin ( JSFiddle ):

let c = 4210330 // your color in decimal format
let rgb = [(c & 0xff0000) >> 16,  (c & 0x00ff00) >> 8,  (c & 0x0000ff)]

// Vanilla JS:
document..getElementById('some-element').style.color = 'rgb(' + rgb + ')'
// jQuery:
$('#some-element').css('color', 'rgb(' + rgb + ')')

Bu, #some-elementCSS colorözelliğini olarak ayarlar rgb(64, 62, 154).


10

Belirli sayıda karakterle kısıtlanmış / doldurulmuş:

function decimalToHex(decimal, chars) {
    return (decimal + Math.pow(16, chars)).toString(16).slice(-chars).toUpperCase();
}

2
Bu bir sayıyı sıfırlar ve sıfırlar önde gelen bir dize hex VE pedleri dönüştürür, bu güzel!
Gordon

10

İşte kesilmiş bir ECMAScript 6 sürümü:

const convert = {
  bin2dec : s => parseInt(s, 2).toString(10),
  bin2hex : s => parseInt(s, 2).toString(16),
  dec2bin : s => parseInt(s, 10).toString(2),
  dec2hex : s => parseInt(s, 10).toString(16),
  hex2bin : s => parseInt(s, 16).toString(2),
  hex2dec : s => parseInt(s, 16).toString(10)
};

convert.bin2dec('111'); // '7'
convert.dec2hex('42');  // '2a'
convert.hex2bin('f8');  // '11111000'
convert.dec2bin('22');  // '10110'

@HypersoftSystems ile güçlü bir anlaşmazlık halinde, ortamınız veya durumunuz sizi karşılıyorsa, ES6'yı kullanın. Her komut dosyasının eski bootleg tercümanlarında çalışması gerekmez, ayrıca babel bir nedenden dolayı vardır. Ve son olarak, eğer biliyorsan ES6 çok daha okunaklı. Standart JS cevapları vermenin daha fazla insana yardımcı olabileceğini söyledi, ancak eski JS sürümleri için başka cevaplar olduğu düşünüldüğünde, bir ES6 cevabına sahip olmak sadece yararlıdır, "bu gün içinde nasıl yaptım" rant kesinlikle gerekli değildir.
WiR3D

Opinons gerçek yapmaz, bu nedenle "argümanınız" geçersizdir. @ WiR3D
Hypersoft Systems

@HypersoftSystems sizinki kadar geçerli değilse, sizinki kadar geçerli olduğundan ve bağlamı çoğu modern uygulamada muhtemelen geçersiz olan bir bağlamla sınırladığı için.
WiR3D

kullanıcı hatası: "aynen belirtildiği gibi", "muhtemelen" ve "çoğu".
Hypersoft Systems

9
function dec2hex(i)
{
  var result = "0000";
  if      (i >= 0    && i <= 15)    { result = "000" + i.toString(16); }
  else if (i >= 16   && i <= 255)   { result = "00"  + i.toString(16); }
  else if (i >= 256  && i <= 4095)  { result = "0"   + i.toString(16); }
  else if (i >= 4096 && i <= 65535) { result =         i.toString(16); }
  return result
}

1
+1 teşekkürler! CSS ile çalışırken, toString (16) önemlidir, böylece FF0000
Tyler Egeto

7
css (veya css tarzı renk özelliklerini kabul eden svg) ile çalışırken color: rgb(r,g,b)rg ve b'nin ondalık sayı olduğu yeri yazarak tüm sorunu azaltabilirsiniz.
telent

1
Olması gereken:function decimalToHexString(i) { var result = "00"; if (i >= 0 && i <= 15) { result += "000" + i.toString(16); } else if (i >= 16 && i <= 255) { result += "00" + i.toString(16); } else if (i >= 256 && i <= 4095) { result += "0" + i.toString(16); } else if (i >= 4096 && i <= 65535) { result += i.toString(16); } return result }
Aykut Çevik

9

Bir sayıyı bir RGBA renk değerinin onaltılı gösterimine dönüştürmek istiyorsanız, bunu buradan birkaç ipucunun en yararlı kombinasyonu olarak buldum:

function toHexString(n) {
    if(n < 0) {
        n = 0xFFFFFFFF + n + 1;
    }
    return "0x" + ("00000000" + n.toString(16).toUpperCase()).substr(-8);
}

8

AFAIK yorumu 57807 yanlıştır ve şöyle bir şey olmalıdır: var hex = Number (d) .toString (16); var hex yerine = parseInt (d, 16);

function decimalToHex(d, padding) {
    var hex = Number(d).toString(16);
    padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;

    while (hex.length < padding) {
        hex = "0" + hex;
    }

    return hex;
}

6

Ve eğer sayı negatifse?

İşte benim versiyonum.

function hexdec (hex_string) {
    hex_string=((hex_string.charAt(1)!='X' && hex_string.charAt(1)!='x')?hex_string='0X'+hex_string : hex_string);
    hex_string=(hex_string.charAt(2)<8 ? hex_string =hex_string-0x00000000 : hex_string=hex_string-0xFFFFFFFF-1);
    return parseInt(hex_string, 10);
}

5

Oldukça büyük bir döngüde hex dizesine dönüşüm yapıyorum, bu yüzden en hızlı olanı bulmak için birkaç teknik denedim. Sonuç olarak, sabit uzunluklu bir dize var ve negatif değerleri düzgün kodlamak (-1 => ff..f).

.toString(16)Negatif değerlerin doğru şekilde kodlanması gerektiğinden Simple benim için çalışmadı. Aşağıdaki kod şimdiye kadar 1-2 bayt değerleri üzerinde test ettiğim en hızlı (not symbolsalmak istediğiniz çıkış sembolleri sayısını tanımlar, yani 4 bayt tam sayı için 8'e eşit olmalıdır):

var hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
function getHexRepresentation(num, symbols) {
    var result = '';
    while (symbols--) {
        result = hex[num & 0xF] + result;
        num >>= 4;
    }
    return result;
}

.toString(16)1-2 bayt sayılara göre daha hızlı ve daha büyük sayılarda ( symbols> = 6 olduğunda) daha yavaş performans gösterir, ancak yine de negatif değerleri düzgün şekilde kodlayan yöntemlerden daha iyi performans göstermelidir.


5

Kabul edilen yanıtın belirttiği gibi, ondalıktan onaltılıya dönüştürmenin en kolay yolu var hex = dec.toString(16). Ancak, dize gösterimlerinin "12".toString(16)doğru çalışmasını sağladığından, dize dönüşümü eklemeyi tercih edebilirsiniz .

// Avoids a hard-to-track-down bug by returning `c` instead of `12`
(+"12").toString(16);

İşlemi tersine çevirmek için, daha kısa olduğu için aşağıdaki çözümü de kullanabilirsiniz.

var dec = +("0x" + hex);

Google Chrome ve Firefox'ta daha yavaş görünüyor, ancak Opera'da önemli ölçüde daha hızlı. Bkz. Http://jsperf.com/hex-to-dec .


5

JavaScript'te ondalık sayı onaltılık biçime nasıl dönüştürülür

İşlevler ve diziler karışıklığı içermeyen, vahşice temiz / basit bir ondalık-onaltılı dönüşüm bulamadım ... bu yüzden bunu kendim yapmak zorunda kaldım.

function DecToHex(decimal) { // Data (decimal)

    length = -1;    // Base string length
    string = '';    // Source 'string'

    characters = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ]; // character array

    do { // Grab each nibble in reverse order because JavaScript has no unsigned left shift

        string += characters[decimal & 0xF];   // Mask byte, get that character
        ++length;                              // Increment to length of string

    } while (decimal >>>= 4); // For next character shift right 4 bits, or break on 0

    decimal += 'x'; // Convert that 0 into a hex prefix string -> '0x'

    do
        decimal += string[length];
    while (length--); // Flip string forwards, with the prefixed '0x'

    return (decimal); // return (hexadecimal);
}

/* Original: */

D = 3678;    // Data (decimal)
C = 0xF;    // Check
A = D;        // Accumulate
B = -1;        // Base string length
S = '';        // Source 'string'
H = '0x';    // Destination 'string'

do {
    ++B;
    A& = C;

    switch(A) {
        case 0xA: A='A'
        break;

        case 0xB: A='B'
        break;

        case 0xC: A='C'
        break;

        case 0xD: A='D'
        break;

        case 0xE: A='E'
        break;

        case 0xF: A='F'
        break;

        A = (A);
    }
    S += A;

    D >>>= 0x04;
    A = D;
} while(D)

do
    H += S[B];
while (B--)

S = B = A = C = D; // Zero out variables
alert(H);    // H: holds hexadecimal equivalent

5
Oh my ... bu, bunu daha çirkin kodlama tarzında yapılan, gerçekten korkunç, korkunç bir yol. Dürüst olmak gerekirse: satır sonları ve girinti ile ilgili sorun nedir? Tek harfli değişkenler? Gerçekten mi?
Victor Schröder

1
Düzeltildi. Bu şekilde korkunç mu? Ve stil daha iyi mi ?? Aslında harflerle yazıldığından "kelimenin tam anlamıyla" her adımda anlamanın daha kolay olacağını düşündüm ... bazen oldukça aptal olabilirim
JonLikeSquirrel

4
Üzgünüm, evet, hala korkunç. Kodunuz hala çok sayıda verimsiz döngü kullanıyor ve diğer sorunların yanı sıra genel ad alanını kirletiyor. Yaklaşımın kendisi, basit bir işlev çağrısı ile gerçekleştirilebilecek bir görev için aşırıdır. JS'de kodlama stilinizi geliştirmek istiyorsanız, w3.org/wiki/JavaScript_best_practices ve google.github.io/styleguide/javascriptguide.xml gibi materyalleri okumanızı önemle tavsiye ederim . Konu hakkında sadece google.
Victor Schröder

1
Chrome'da bir hız testi yaptım ve aşırı doldurma işlevim .toString (16) 'dan% 30 daha hızlı, Firefox'ta işlevim .toString (16)' dan% 40 daha yavaş ... Chrome, aşırı döngülerimin DAHA verimli olduğunu kanıtlıyor Firefox'un yerel .toString (16) işlevine kıyasla, Firefox neden daha fazla kişinin Chrome'u tercih ettiğini kanıtlıyor. Yoksa geriye mi? Bir gün Chrome, her iki durumda da beni yanlış yapan daha hızlı bir .toString (16) sürümüne bile güncelleyebilir! Her iki durumda da tamamen yanlış değilim ve tamamen doğru değilsiniz. Nefsim bir yana, en azından% 30'unu anladım. ;)
JonLikeSquirrel

2
Her biri tek karakter içeren bir dizi dizeyi bildirmeniz gerekmez. Bir karakter dizesi bildirmeniz yeterlidir. Köşeli parantez kullanarak, bir dizide yaptığınız gibi bir dizeden bir karakter alabilirsiniz.
David Spector

3

Hepsini özetlemek gerekirse;

function toHex(i, pad) {

  if (typeof(pad) === 'undefined' || pad === null) {
    pad = 2;
  } 

  var strToParse = i.toString(16);

  while (strToParse.length < pad) {
    strToParse = "0" + strToParse;
  }

  var finalVal =  parseInt(strToParse, 16);

  if ( finalVal < 0 ) {
    finalVal = 0xFFFFFFFF + finalVal + 1;
  }

  return finalVal;
}

Ancak, sonunda (örneğin renkler için) bir tam sayıya dönüştürmeniz gerekmiyorsa, değerlerin negatif olmadığından emin olmak yeterli olacaktır.


2

İkisinin tamamlayıcısını (negatif sayılar dahil) kullanan, negatif veya pozitif olup olmadığını kontrol etmeden net bir cevap bulamadım. Bunun için çözümümü bir bayta gösterdim:

((0xFF + number +1) & 0x0FF).toString(16);

Bu talimatı, yalnızca FFilgili yerlere eklediğiniz herhangi bir sayı bayt için kullanabilirsiniz . Örneğin, iki bayta:

((0xFFFF + number +1) & 0x0FFFF).toString(16);

Onaltılık dizeye dizi tamsayısı atamak istiyorsanız:

s = "";
for(var i = 0; i < arrayNumber.length; ++i) {
    s += ((0xFF + arrayNumber[i] +1) & 0x0FF).toString(16);
}

2

'Tam' JavaScript veya CSS temsiline dönüştürmek istiyorsanız, aşağıdakine benzer bir şey kullanabilirsiniz:

  numToHex = function(num) {
    var r=((0xff0000&num)>>16).toString(16),
        g=((0x00ff00&num)>>8).toString(16),
        b=(0x0000ff&num).toString(16);
    if (r.length==1) { r = '0'+r; }
    if (g.length==1) { g = '0'+g; }
    if (b.length==1) { b = '0'+b; }
    return '0x'+r+g+b;                 // ('#' instead of'0x' for CSS)
  };

  var dec = 5974678;
  console.log( numToHex(dec) );        // 0x5b2a96


1

Büyük tamsayıları, örneğin Number.MAX_SAFE_INTEGER - 9007199254740991'den büyük Sayıları dönüştürmek istiyorsanız, aşağıdaki kodu kullanabilirsiniz

const hugeNumber = "9007199254740991873839" // Make sure its in String
const hexOfHugeNumber = BigInt(hugeNumber).toString(16);
console.log(hexOfHugeNumber)


1

Bu Prestaul ve Tod'nun çözümlerine dayanmaktadır. Bununla birlikte, bu, bir değişkenin değişen büyüklüğünü (örn. Bir mikrodenetleyici seri günlüğünden işaretli değeri ayrıştırma) açıklayan bir genellemedir.

function decimalToPaddedHexString(number, bitsize)
{ 
  let byteCount = Math.ceil(bitsize/8);
  let maxBinValue = Math.pow(2, bitsize)-1;

  /* In node.js this function fails for bitsize above 32bits */
  if (bitsize > 32)
    throw "number above maximum value";

  /* Conversion to unsigned form based on  */
  if (number < 0)
    number = maxBinValue + number + 1;

  return "0x"+(number >>> 0).toString(16).toUpperCase().padStart(byteCount*2, '0');
}

Test komut dosyası:

for (let n = 0 ; n < 64 ; n++ ) { 
     let s=decimalToPaddedHexString(-1, n); 
     console.log(`decimalToPaddedHexString(-1,${(n+"").padStart(2)}) = ${s.padStart(10)} = ${("0b"+parseInt(s).toString(2)).padStart(34)}`);
   }

Test sonuçları:

decimalToPaddedHexString(-1, 0) =        0x0 =                                0b0
decimalToPaddedHexString(-1, 1) =       0x01 =                                0b1
decimalToPaddedHexString(-1, 2) =       0x03 =                               0b11
decimalToPaddedHexString(-1, 3) =       0x07 =                              0b111
decimalToPaddedHexString(-1, 4) =       0x0F =                             0b1111
decimalToPaddedHexString(-1, 5) =       0x1F =                            0b11111
decimalToPaddedHexString(-1, 6) =       0x3F =                           0b111111
decimalToPaddedHexString(-1, 7) =       0x7F =                          0b1111111
decimalToPaddedHexString(-1, 8) =       0xFF =                         0b11111111
decimalToPaddedHexString(-1, 9) =     0x01FF =                        0b111111111
decimalToPaddedHexString(-1,10) =     0x03FF =                       0b1111111111
decimalToPaddedHexString(-1,11) =     0x07FF =                      0b11111111111
decimalToPaddedHexString(-1,12) =     0x0FFF =                     0b111111111111
decimalToPaddedHexString(-1,13) =     0x1FFF =                    0b1111111111111
decimalToPaddedHexString(-1,14) =     0x3FFF =                   0b11111111111111
decimalToPaddedHexString(-1,15) =     0x7FFF =                  0b111111111111111
decimalToPaddedHexString(-1,16) =     0xFFFF =                 0b1111111111111111
decimalToPaddedHexString(-1,17) =   0x01FFFF =                0b11111111111111111
decimalToPaddedHexString(-1,18) =   0x03FFFF =               0b111111111111111111
decimalToPaddedHexString(-1,19) =   0x07FFFF =              0b1111111111111111111
decimalToPaddedHexString(-1,20) =   0x0FFFFF =             0b11111111111111111111
decimalToPaddedHexString(-1,21) =   0x1FFFFF =            0b111111111111111111111
decimalToPaddedHexString(-1,22) =   0x3FFFFF =           0b1111111111111111111111
decimalToPaddedHexString(-1,23) =   0x7FFFFF =          0b11111111111111111111111
decimalToPaddedHexString(-1,24) =   0xFFFFFF =         0b111111111111111111111111
decimalToPaddedHexString(-1,25) = 0x01FFFFFF =        0b1111111111111111111111111
decimalToPaddedHexString(-1,26) = 0x03FFFFFF =       0b11111111111111111111111111
decimalToPaddedHexString(-1,27) = 0x07FFFFFF =      0b111111111111111111111111111
decimalToPaddedHexString(-1,28) = 0x0FFFFFFF =     0b1111111111111111111111111111
decimalToPaddedHexString(-1,29) = 0x1FFFFFFF =    0b11111111111111111111111111111
decimalToPaddedHexString(-1,30) = 0x3FFFFFFF =   0b111111111111111111111111111111
decimalToPaddedHexString(-1,31) = 0x7FFFFFFF =  0b1111111111111111111111111111111
decimalToPaddedHexString(-1,32) = 0xFFFFFFFF = 0b11111111111111111111111111111111
Thrown: 'number above maximum value'

Not: Neden 32 bit boyutunun üzerinde başarısız olduğundan emin değilim


-3

İşte benim çözümüm:

hex = function(number) {
  return '0x' + Math.abs(number).toString(16);
}

Soru şöyle diyor: "JavaScript'te ondalık sayı onaltılık biçime nasıl dönüştürülür" . İken, soru onaltılık dize 0x ayırt etmek onaltılık kodları eklenir bilmeli kodu yazıyor bir 0x öneki, kimseyle başlaması gerektiğini belirtmez onaltılık kodları gelen programatik tanımlayıcıları ve diğer numaralar (1234 olabilir onaltılık, ondalık veya sekizli bile).

Bu nedenle, bu soruyu doğru şekilde yanıtlamak için komut dosyası yazma amacıyla 0x önekini eklemelisiniz.

Math.abs (N) işlevi, negatifleri pozitiflere dönüştürür ve bir bonus olarak, birisinin odun parçalayıcıdan geçirdiği görülmez.

İstediğim cevabın alan genişliği belirleyicisi olurdu, bu yüzden örneğin 8/16/32/64 bit değerlerini onaltılık bir düzenleme uygulamasında listelediğiniz şekilde gösterebiliriz. Gerçek, doğru cevap budur.


1
Genel kodlama pratiğinde, bir harfle başlayan herhangi bir alfa-sayısal dizi, NUMARA DEĞİLDİR. Örneğin: ABCDEF012345678, gezegendeki hemen hemen her kodlama dilinde geçerli bir tanımlayıcıdır.
Hypersoft Systems

1
Oh, ve 0x öneki javascript için bir sorun değildir: Number('0xFF') === 255;ters işlemi isteyen tüm millet için.
Hypersoft Systems
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.