|
|
| Line 14: |
Line 14: |
| |
|
|
|
| |
==Commands== |
|
==Commands== |
| − |
Occasional conversions can be performed by entering commands. In Vim, put the cursor on 0x12345 and type <tt>:echo</tt> then Space Ctrl-R Ctrl-W Enter. That will execute <tt>:echo 0x12345</tt> which displays 74565 (decimal equivalent of hex 12345). |
+ |
Occasional conversions can be performed by entering commands. In Vim, put the cursor on 0x12345 and type <code>:echo</code> then Space Ctrl-R Ctrl-W Enter. That will execute <code>:echo 0x12345</code> which displays 74565 (decimal equivalent of hex 12345). |
| |
|
|
|
| − |
An example of converting decimal to hex would be to enter <tt>:echo printf('%x',74565)</tt> which displays 12345 (hex equivalent of decimal 74565). |
+ |
An example of converting decimal to hex would be to enter <code>:echo printf('%x',74565)</code> which displays 12345 (hex equivalent of decimal 74565). |
| |
|
|
|
| − |
In addition, the expression register can be used to enter converted numbers while typing. In insert mode, press Ctrl-R then <tt>=</tt> then the expression wanted, then press Enter. The value of the expression is inserted, and you will remain in insert mode. For example, <tt><C-R>=0x09ab<Enter></tt> will insert <tt>2475</tt>, and <tt><C-R>=printf('0x%04x',2475)<Enter></tt> will insert <tt>0x09ab</tt>. |
+ |
In addition, the expression register can be used to enter converted numbers while typing. In insert mode, press Ctrl-R then <code>=</code> then the expression wanted, then press Enter. The value of the expression is inserted, and you will remain in insert mode. For example, <code><C-R>=0x09ab<Enter></code> will insert <code>2475</code>, and <code><C-R>=printf('0x%04x',2475)<Enter></code> will insert <code>0x09ab</code>. |
| |
|
|
|
| − |
In normal mode, type <tt>ga</tt> to display the decimal and hex values for the character under the cursor, or type <tt>g8</tt> to display the hex bytes for a UTF-8 character. |
+ |
In normal mode, type <code>ga</code> to display the decimal and hex values for the character under the cursor, or type <code>g8</code> to display the hex bytes for a UTF-8 character. |
| |
|
|
|
| − |
The following commands illustrate other simple techniques to convert strings to numbers which are displayed in decimal (the <tt>:echo</tt> is just for illustration; these techniques would be used in a script). The first shows that adding zero to a string converts the string to a number. |
+ |
The following commands illustrate other simple techniques to convert strings to numbers which are displayed in decimal (the <code>:echo</code> is just for illustration; these techniques would be used in a script). The first shows that adding zero to a string converts the string to a number. |
| |
|
|
|
| |
{| class="wikitable" |
|
{| class="wikitable" |
| |
!Command !! Output !! Description |
|
!Command !! Output !! Description |
| |
|- |
|
|- |
| − |
| <tt>:echo '0012' + 0</tt> || 10 || octal 12 due to leading zero |
+ |
| <code>:echo '0012' + 0</code> || 10 || octal 12 due to leading zero |
| |
|- |
|
|- |
| − |
| <tt>:echo str2nr('0012')</tt> || 12 || decimal 12 (leading zeros ignored) |
+ |
| <code>:echo str2nr('0012')</code> || 12 || decimal 12 (leading zeros ignored) |
| |
|- |
|
|- |
| − |
| <tt>:echo str2nr('0x0a2f', 16)</tt> || 2607 || hex a2f |
+ |
| <code>:echo str2nr('0x0a2f', 16)</code> || 2607 || hex a2f |
| |
|- |
|
|- |
| − |
| <tt>:echo str2nr('0a2f', 16)</tt> || 2607 || same ('0x' not required with base 16) |
+ |
| <code>:echo str2nr('0a2f', 16)</code> || 2607 || same ('0x' not required with base 16) |
| |
|- |
|
|- |
| − |
| <tt>:echo str2nr('^R^W', 16)</tt> || (decimal) || hex word under cursor (press Ctrl-R Ctrl-W) |
+ |
| <code>:echo str2nr('^R^W', 16)</code> || (decimal) || hex word under cursor (press Ctrl-R Ctrl-W) |
| |
|} |
|
|} |
| |
|
|
|
| Line 43: |
Line 43: |
| |
!Command !! Output !! Description |
|
!Command !! Output !! Description |
| |
|- |
|
|- |
| − |
| <tt>:echo printf('%x', 1234)</tt> || 4d2 || decimal 1234 in hex |
+ |
| <code>:echo printf('%x', 1234)</code> || 4d2 || decimal 1234 in hex |
| |
|- |
|
|- |
| − |
| <tt>:echo printf('%04x', 1234)</tt> || 04d2 || same, with leading zeros to four digits |
+ |
| <code>:echo printf('%04x', 1234)</code> || 04d2 || same, with leading zeros to four digits |
| |
|- |
|
|- |
| − |
| <tt>:echo printf('%x', ^R^W)</tt> || (hex) || decimal word under cursor (press Ctrl-R Ctrl-W) |
+ |
| <code>:echo printf('%x', ^R^W)</code> || (hex) || decimal word under cursor (press Ctrl-R Ctrl-W) |
| |
|} |
|
|} |
| |
|
|
|
| |
==Copying a hex number as decimal== |
|
==Copying a hex number as decimal== |
| − |
With the following mapping, you can put the cursor on a hex number and press <tt>\h</tt> (assuming the default backslash leader) to yank the value of the hex number (using <tt>:let</tt> means the equivalent decimal string is copied). You can then move the cursor elsewhere and press <tt>p</tt> to paste the decimal value. |
+ |
With the following mapping, you can put the cursor on a hex number and press <code>\h</code> (assuming the default backslash leader) to yank the value of the hex number (using <code>:let</code> means the equivalent decimal string is copied). You can then move the cursor elsewhere and press <code>p</code> to paste the decimal value. |
| |
<pre> |
|
<pre> |
| |
nnoremap \h :let @@=<C-R><C-W><CR> |
|
nnoremap \h :let @@=<C-R><C-W><CR> |
| |
</pre> |
|
</pre> |
| |
|
|
|
| − |
Alternatively, you can use a global variable to avoid using a register. With these mappings, <tt>\h</tt> will yank a hex value, and <tt>\p</tt> will paste the decimal string: |
+ |
Alternatively, you can use a global variable to avoid using a register. With these mappings, <code>\h</code> will yank a hex value, and <code>\p</code> will paste the decimal string: |
| |
<pre> |
|
<pre> |
| |
nnoremap \h :let Value=<C-R><C-W><CR> |
|
nnoremap \h :let Value=<C-R><C-W><CR> |
| Line 102: |
Line 102: |
| |
</pre> |
|
</pre> |
| |
|
|
|
| − |
The above defines user commands <tt>:Dec2hex</tt> and <tt>:Hex2dec</tt> that will either display the result of converting a number that you enter, or will convert all numbers in selected text. A decimal number is a word consisting only of decimal digits, while a hex number consists of "0x" followed by one or more hex digits. |
+ |
The above defines user commands <code>:Dec2hex</code> and <code>:Hex2dec</code> that will either display the result of converting a number that you enter, or will convert all numbers in selected text. A decimal number is a word consisting only of decimal digits, while a hex number consists of "0x" followed by one or more hex digits. |
| |
|
|
|
| |
If no argument is entered with these commands, a range may be specified. The default range is the current line. A visual selection (character, line, or block) can also specify a range. When using a visual block (selection starts with Ctrl-V, or Ctrl-Q if Ctrl-V is used for paste), only numbers inside the block are converted. Example commands: |
|
If no argument is entered with these commands, a range may be specified. The default range is the current line. A visual selection (character, line, or block) can also specify a range. When using a visual block (selection starts with Ctrl-V, or Ctrl-Q if Ctrl-V is used for paste), only numbers inside the block are converted. Example commands: |
| Line 109: |
Line 109: |
| |
!Command !! Description |
|
!Command !! Description |
| |
|- |
|
|- |
| − |
| <tt>:Dec2hex 496</tt> || Displays 1f0 (hex equivalent of decimal 496). |
+ |
| <code>:Dec2hex 496</code> || Displays 1f0 (hex equivalent of decimal 496). |
| |
|- |
|
|- |
| − |
| <tt>:Dec2hex</tt> || Converts all decimal numbers to hex in current line. |
+ |
| <code>:Dec2hex</code> || Converts all decimal numbers to hex in current line. |
| |
|- |
|
|- |
| − |
| <tt>:'<,>'Dec2hex</tt> || Same, for all visually selected text (v, V, or ^V). |
+ |
| <code>:'<,>'Dec2hex</code> || Same, for all visually selected text (v, V, or ^V). |
| |
|- |
|
|- |
| − |
| <tt>:%Dec2hex</tt> || Same, for all lines in buffer. |
+ |
| <code>:%Dec2hex</code> || Same, for all lines in buffer. |
| |
|- |
|
|- |
| − |
| <tt>:Hex2dec 0x1f0</tt> || Displays 496 (decimal equivalent of hex 1f0). |
+ |
| <code>:Hex2dec 0x1f0</code> || Displays 496 (decimal equivalent of hex 1f0). |
| |
|- |
|
|- |
| − |
| <tt>:Hex2dec 1f0</tt> || Same ("0x" is optional in an argument). |
+ |
| <code>:Hex2dec 1f0</code> || Same ("0x" is optional in an argument). |
| |
|- |
|
|- |
| − |
| <tt>:Hex2dec</tt> || Converts all "0x" hex numbers to decimal in current line. |
+ |
| <code>:Hex2dec</code> || Converts all "0x" hex numbers to decimal in current line. |
| |
|- |
|
|- |
| − |
| <tt>:'<,>'Hex2dec</tt> || Same, for all visually selected text (v, V, or ^V). |
+ |
| <code>:'<,>'Hex2dec</code> || Same, for all visually selected text (v, V, or ^V). |
| |
|- |
|
|- |
| − |
| <tt>:%Hex2dec</tt> || Same, for all lines in buffer. |
+ |
| <code>:%Hex2dec</code> || Same, for all lines in buffer. |
| |
|} |
|
|} |
| |
|
|
|
| Line 188: |
Line 188: |
| |
!WORD under cursor !! Output !! Description |
|
!WORD under cursor !! Output !! Description |
| |
|- |
|
|- |
| − |
| <tt>32</tt> || 32 -> 0x20, -(0xFFFFFFE0) || decimal 32 in hex, decimal -32 in hex |
+ |
| <code>32</code> || 32 -> 0x20, -(0xFFFFFFE0) || decimal 32 in hex, decimal -32 in hex |
| |
|- |
|
|- |
| − |
| <tt>-32</tt> || -32 -> 0xFFFFFFE0, -(0x20) || decimal -32 in hex, decimal 32 in hex |
+ |
| <code>-32</code> || -32 -> 0xFFFFFFE0, -(0x20) || decimal -32 in hex, decimal 32 in hex |
| |
|- |
|
|- |
| − |
| <tt>0x32</tt> || 0x32 -> 50 || hex 32 in decimal |
+ |
| <code>0x32</code> || 0x32 -> 50 || hex 32 in decimal |
| |
|- |
|
|- |
| − |
| <tt>h'38</tt> || 0x38 -> 56 || hex 38 in decimal |
+ |
| <code>h'38</code> || 0x38 -> 56 || hex 38 in decimal |
| |
|- |
|
|- |
| − |
| <tt>#123</tt> || 0x123 -> 291 || hex 123 in decimal |
+ |
| <code>#123</code> || 0x123 -> 291 || hex 123 in decimal |
| |
|- |
|
|- |
| − |
| <tt>0xFFFFFFE0</tt> || 0xFFFFFFE0 -> -32 || 32 bit hex FFFFFFE0 in decimal |
+ |
| <code>0xFFFFFFE0</code> || 0xFFFFFFE0 -> -32 || 32 bit hex FFFFFFE0 in decimal |
| |
|- |
|
|- |
| − |
| <tt>0xFFFE00</tt> || 0xFFFE00 -> 16776704 (-512) || hex FFFE00 in decimal, equivalent negative value on a 24 bits machine |
+ |
| <code>0xFFFE00</code> || 0xFFFE00 -> 16776704 (-512) || hex FFFE00 in decimal, equivalent negative value on a 24 bits machine |
| |
|- |
|
|- |
| − |
| <tt>ab</tt> || 0xab -> 171 (-85) || hex ab in decimal, equivalent negative value on a 8 bits machine |
+ |
| <code>ab</code> || 0xab -> 171 (-85) || hex ab in decimal, equivalent negative value on a 8 bits machine |
| |
|} |
|
|} |
| |
|
|
|
| Line 216: |
Line 216: |
| |
</pre> |
|
</pre> |
| |
|
|
|
| − |
More is needed to make it work. I had to do the following on a Linux system, but I suspect a setting regarding register <tt>*</tt> is also being used (it assumes that the selected text is in the <tt>*</tt> register). |
+ |
More is needed to make it work. I had to do the following on a Linux system, but I suspect a setting regarding register <code>*</code> is also being used (it assumes that the selected text is in the <code>*</code> register). |
| |
<pre> |
|
<pre> |
| |
set mousemodel=popup |
|
set mousemodel=popup |
| Line 228: |
Line 228: |
| |
*{{script|id=54|text=ConvertBase}} plugin to convert to/from various numeric bases |
|
*{{script|id=54|text=ConvertBase}} plugin to convert to/from various numeric bases |
| |
*[http://www.stringfunction.com/hex-decimal.html Convert Hexadecimal to Decimal Number] online tool to convert hex to dec |
|
*[http://www.stringfunction.com/hex-decimal.html Convert Hexadecimal to Decimal Number] online tool to convert hex to dec |
| − |
* [https://www.codeproject.com/Articles/350252/From-one-to-another-number-system/ From one to another number system], ''article related to creating computer program for conversion of number from one to another number system with source code written in C#'' |
+ |
*[https://www.codeproject.com/Articles/350252/From-one-to-another-number-system/ From one to another number system], ''article related to creating computer program for conversion of number from one to another number system with source code written in C#'' |
| |
|
|
|
| |
==Comments== |
|
==Comments== |
This tip shows how to convert numbers from hexadecimal to decimal, and the reverse. A variety of methods are given, including some simple commands you can enter, and some scripts to easily replace hex numbers with decimal, or to replace decimal with hex. Handling percent-encoded text is also discussed, and there are links to tips showing how to edit a binary file in hex.
Commands
Occasional conversions can be performed by entering commands. In Vim, put the cursor on 0x12345 and type :echo then Space Ctrl-R Ctrl-W Enter. That will execute :echo 0x12345 which displays 74565 (decimal equivalent of hex 12345).
An example of converting decimal to hex would be to enter :echo printf('%x',74565) which displays 12345 (hex equivalent of decimal 74565).
In addition, the expression register can be used to enter converted numbers while typing. In insert mode, press Ctrl-R then = then the expression wanted, then press Enter. The value of the expression is inserted, and you will remain in insert mode. For example, <C-R>=0x09ab<Enter> will insert 2475, and <C-R>=printf('0x%04x',2475)<Enter> will insert 0x09ab.
In normal mode, type ga to display the decimal and hex values for the character under the cursor, or type g8 to display the hex bytes for a UTF-8 character.
The following commands illustrate other simple techniques to convert strings to numbers which are displayed in decimal (the :echo is just for illustration; these techniques would be used in a script). The first shows that adding zero to a string converts the string to a number.
| Command | Output | Description
|
:echo '0012' + 0 | 10 | octal 12 due to leading zero
|
:echo str2nr('0012') | 12 | decimal 12 (leading zeros ignored)
|
:echo str2nr('0x0a2f', 16) | 2607 | hex a2f
|
:echo str2nr('0a2f', 16) | 2607 | same ('0x' not required with base 16)
|
:echo str2nr('^R^W', 16) | (decimal) | hex word under cursor (press Ctrl-R Ctrl-W)
|
The following convert decimal numbers to hex strings.
| Command | Output | Description
|
:echo printf('%x', 1234) | 4d2 | decimal 1234 in hex
|
:echo printf('%04x', 1234) | 04d2 | same, with leading zeros to four digits
|
:echo printf('%x', ^R^W) | (hex) | decimal word under cursor (press Ctrl-R Ctrl-W)
|
Copying a hex number as decimal
With the following mapping, you can put the cursor on a hex number and press \h (assuming the default backslash leader) to yank the value of the hex number (using :let means the equivalent decimal string is copied). You can then move the cursor elsewhere and press p to paste the decimal value.
nnoremap \h :let @@=<C-R><C-W><CR>
Alternatively, you can use a global variable to avoid using a register. With these mappings, \h will yank a hex value, and \p will paste the decimal string:
nnoremap \h :let Value=<C-R><C-W><CR>
nnoremap \p :if exists('Value')<Bar>normal i<C-R>=Value<CR><Esc><Bar>:endif<CR>
User commands
Put the following in your vimrc to define user commands to convert between hex and decimal. You can convert a number entered on the command line, or all numbers in selected text.
command! -nargs=? -range Dec2hex call s:Dec2hex(<line1>, <line2>, '<args>')
function! s:Dec2hex(line1, line2, arg) range
if empty(a:arg)
if histget(':', -1) =~# "^'<,'>" && visualmode() !=# 'V'
let cmd = 's/\%V\<\d\+\>/\=printf("0x%x",submatch(0)+0)/g'
else
let cmd = 's/\<\d\+\>/\=printf("0x%x",submatch(0)+0)/g'
endif
try
execute a:line1 . ',' . a:line2 . cmd
catch
echo 'Error: No decimal number found'
endtry
else
echo printf('%x', a:arg + 0)
endif
endfunction
command! -nargs=? -range Hex2dec call s:Hex2dec(<line1>, <line2>, '<args>')
function! s:Hex2dec(line1, line2, arg) range
if empty(a:arg)
if histget(':', -1) =~# "^'<,'>" && visualmode() !=# 'V'
let cmd = 's/\%V0x\x\+/\=submatch(0)+0/g'
else
let cmd = 's/0x\x\+/\=submatch(0)+0/g'
endif
try
execute a:line1 . ',' . a:line2 . cmd
catch
echo 'Error: No hex number starting "0x" found'
endtry
else
echo (a:arg =~? '^0x') ? a:arg + 0 : ('0x'.a:arg) + 0
endif
endfunction
The above defines user commands :Dec2hex and :Hex2dec that will either display the result of converting a number that you enter, or will convert all numbers in selected text. A decimal number is a word consisting only of decimal digits, while a hex number consists of "0x" followed by one or more hex digits.
If no argument is entered with these commands, a range may be specified. The default range is the current line. A visual selection (character, line, or block) can also specify a range. When using a visual block (selection starts with Ctrl-V, or Ctrl-Q if Ctrl-V is used for paste), only numbers inside the block are converted. Example commands:
| Command | Description
|
:Dec2hex 496 | Displays 1f0 (hex equivalent of decimal 496).
|
:Dec2hex | Converts all decimal numbers to hex in current line.
|
:'<,>'Dec2hex | Same, for all visually selected text (v, V, or ^V).
|
:%Dec2hex | Same, for all lines in buffer.
|
:Hex2dec 0x1f0 | Displays 496 (decimal equivalent of hex 1f0).
|
:Hex2dec 1f0 | Same ("0x" is optional in an argument).
|
:Hex2dec | Converts all "0x" hex numbers to decimal in current line.
|
:'<,>'Hex2dec | Same, for all visually selected text (v, V, or ^V).
|
:%Hex2dec | Same, for all lines in buffer.
|
Converting strings
Following are some methods for working with percent-encoded text, and for showing ASCII characters in hex.
" Convert current line to percent-encoded hex for disallowed punctuation.
" Example: line "A/C[123]D\E" is converted to "A%2FC%5B123%5DD%5CE".
nnoremap <Leader>h :s@\([;(){}\[\]+ ,\-><\|=%&^\\/"']\)@\='%'.printf('%02X',char2nr(submatch(1)))@g<CR>
" Convert percent-encoded hex in current line to text (reverse of above).
nnoremap <Leader>H :s@%\(\x\x\)@\=nr2char('0x'.submatch(1))@g<CR>
" Convert each ASCII character in a string to hex bytes.
" Example: ":Str2hex ABC 123" displays "41 42 43 20 31 32 33".
command! -nargs=* Str2hex echo Str2hex(<q-args>)
function! Str2hex(arg)
return join(map(split(a:arg, '\zs'), 'printf("%02x", char2nr(v:val))'))
endfunction
General functions
A script could use the following functions for conversions between decimal and hex.
" Return hex string equivalent to given decimal string or number.
function! Dec2hex(arg)
return printf('%x', a:arg + 0)
endfunction
" Return number equivalent to given hex string ('0x' is optional).
function! Hex2dec(arg)
return (a:arg =~? '^0x') ? a:arg + 0 : ('0x'.a:arg) + 0
endfunction
Sometimes one just needs to know the value of decimal/hexadecimal value, without changing the text.
Put the following in your vimrc to define user command 'gn' to print the number under the cursor converted to hex/decimal (similar to built-in command 'ga' and 'g8' for ASCII character under the cursor):
nnoremap gn :call DecAndHex(expand("<cWORD>"))<CR>
function! DecAndHex(number)
let ns = '[.,;:''"<>()^_lL]' " number separators
if a:number =~? '^' . ns. '*[-+]\?\d\+' . ns . '*$'
let dec = substitute(a:number, '[^0-9+-]*\([+-]\?\d\+\).*','\1','')
echo dec . printf(' -> 0x%X, -(0x%X)', dec, -dec)
elseif a:number =~? '^' . ns. '*\%\(h''\|0x\|#\)\?\(\x\+\)' . ns . '*$'
let hex = substitute(a:number, '.\{-}\%\(h''\|0x\|#\)\?\(\x\+\).*','\1','')
echon '0x' . hex . printf(' -> %d', eval('0x'.hex))
if strpart(hex, 0,1) =~? '[89a-f]' && strlen(hex) =~? '2\|4\|6'
" for 8/16/24 bits numbers print the equivalent negative number
echon ' ('. float2nr(eval('0x'. hex) - pow(2,4*strlen(hex))) . ')'
endif
echo
else
echo "NaN"
endif
endfunction
Numbers containing character A-F or prefixed with '0x', 'h' or '#' are treated as hexadecimal values:
| WORD under cursor | Output | Description
|
32 | 32 -> 0x20, -(0xFFFFFFE0) | decimal 32 in hex, decimal -32 in hex
|
-32 | -32 -> 0xFFFFFFE0, -(0x20) | decimal -32 in hex, decimal 32 in hex
|
0x32 | 0x32 -> 50 | hex 32 in decimal
|
h'38 | 0x38 -> 56 | hex 38 in decimal
|
#123 | 0x123 -> 291 | hex 123 in decimal
|
0xFFFFFFE0 | 0xFFFFFFE0 -> -32 | 32 bit hex FFFFFFE0 in decimal
|
0xFFFE00 | 0xFFFE00 -> 16776704 (-512) | hex FFFE00 in decimal, equivalent negative value on a 24 bits machine
|
ab | 0xab -> 171 (-85) | hex ab in decimal, equivalent negative value on a 8 bits machine
|
Using external programs
TO DO
- Fix or delete this section.
- The following is from old tip 772. It does not seem helpful, but we should discuss the menus somewhere so I am keeping the text for a while.
This example creates a menu for conversions using the bc calculator which is a standard utility on many Unix-based systems. Visually select the number (without leading '0x'), right click the selection, and select from the popup menu to transform the number.
vmenu 1.220 PopUp.&nr2hex <Esc>:exec("!echo \\"obase=16;".@*."\\" \| bc -l -q ")<CR>
vmenu 1.220 PopUp.hex&2nr <Esc>:exec("!echo \\"ibase=16;".toupper(@*)."\\" \| bc -l -q ")<CR>
More is needed to make it work. I had to do the following on a Linux system, but I suspect a setting regarding register * is also being used (it assumes that the selected text is in the * register).
set mousemodel=popup
vmenu 1.220 PopUp.&nr2hex <Esc>:exec '!echo "obase=16;'.@*.'" \| bc -l -q '<CR>
vmenu 1.220 PopUp.hex&2nr <Esc>:exec '!echo "ibase=16;'.toupper(@*).'" \| bc -l -q '<CR>
See also