What is the general way to convert numbers among hex, oct and binary in OCaml?
For example, how to convert hex 4294967276 (FFFFFFFC) to decimal number?
Thanks!
Nick
It's not clear what you're asking. Numbers are just numbers, really. They don't have a base (ignoring the hardware representation). The time you have a base is when you convert numbers to and from strings. To interpret a string as a decimal integer you can use int_of_string. For other bases, you can use Scanf.sscanf. To convert a number to a decimal string you can use string_of_int. For other bases, you can use Printf.sprintf.
# int_of_string "345";;
- : int = 345
# Scanf.sscanf "FC" "%x" (fun x -> x);;
- : int = 252
# string_of_int 345;;
- : string = "345"
# Printf.sprintf "%X" 252;;
- : string = "FC"
#
Granted, Scanf.sscanf is fairly cumbersome to use. But I don't know of any other conversion functions in the OCaml Standard Library.
Update
As observed by barti_ddu, if you don't mind adding a prefix to your input string you can use int_of_string for all 4 of the bases you mention:
# int_of_string "0xFC";;
- : int = 252
# int_of_string "0o374";;
- : int = 252
# int_of_string "0b11111100";;
- : int = 252
(Or maybe your input already has the prefix, in which case this is a much simpler solution.)
Related
I need to figure out how to read in this data of the filename 'berlin52.tsp'
This is the format I'm using
NAME: berlin52
TYPE: TSP
COMMENT: 52 locations in Berlin (Groetschel)
DIMENSION : 52
EDGE_WEIGHT_TYPE : EUC_2D
NODE_COORD_SECTION
1 565.0 575.0
2 25.0 185.0
3 345.0 750.0
4 945.0 685.0
5 845.0 655.0
6 880.0 660.0
7 25.0 230.0
8 525.0 1000.0
9 580.0 1175.0
10 650.0 1130.0
And this is my current code
# Open input file
infile = open('berlin52.tsp', 'r')
# Read instance header
Name = infile.readline().strip().split()[1] # NAME
FileType = infile.readline().strip().split()[1] # TYPE
Comment = infile.readline().strip().split()[1] # COMMENT
Dimension = infile.readline().strip().split()[1] # DIMENSION
EdgeWeightType = infile.readline().strip().split()[1] # EDGE_WEIGHT_TYPE
infile.readline()
# Read node list
nodelist = []
N = int(intDimension)
for i in range(0, int(intDimension)):
x,y = infile.readline().strip().split()[1:]
nodelist.append([int(x), int(y)])
# Close input file
infile.close()
The code should read in the file, output out a list of tours with the values "1, 2, 3..." and more while the x and y values are stored to be calculated for distances. It can collect the headers, at least. The problem arises when creating a list of nodes.
This is the error I get though
ValueError: invalid literal for int() with base 10: '565.0'
What am I doing wrong here?
This is a file in TSPLIB format. To load it in python, take a look at the python package tsplib95, available through PyPi or on Github
Documentation is available on https://tsplib95.readthedocs.io/
You can convert the TSPLIB file to a networkx graph and retrieve the necessary information from there.
You are feeding the string "565.0" into nodelist.append([int(x), int(y)]).
It is telling you it doesn't like that because that string is not an integer. The .0 at the end makes it a float.
So if you change that to nodelist.append([float(x), float(y)]), as just one possible solution, then you'll see that your problem goes away.
Alternatively, you can try removing or separating the '.0' from your string input.
There are two problem with the code above.I have run the code and found the following problem in lines below:
Dimension = infile.readline().strip().split()[1]
This line should be like this
`Dimension = infile.readline().strip().split()[2]`
instead of 1 it will be 2 because for 1 Dimension = : and for 2 Dimension = 52.
Both are of string type.
Second problem is with line
N = int(intDimension)
It will be
N = int(Dimension)
And lastly in line
for i in range(0, int(intDimension)):
Just simply use
for i in range(0, N):
Now everything will be alright I think.
nodelist.append([int(x), int(y)])
int(x)
function int() cant convert x(string(565.0)) to int because of "."
add
x=x[:len(x)-2]
y=y[:len(y)-2]
to remove ".0"
I'm unable to convert integer regular expression captures values to an array of integers in Julia 0.4.
In Julia 0.3 I could do this with int(), basically like:
c = ["1", "2"] ;
int(c)
But in Julia 0.4, this works for regular strings:
julia> c = ["1", "2"] ;
julia> int(c)
2-element Array{Int64,1}:
1
2
but doesn't work with substrings (i.e. regex captures):
re_dcIV = r"^
([IV])(\S+)\s+
(\d+)\s+
(\d+)\s+
DC\s+
(\S+)\s*$"x ;
line = "V1 1 2 DC 1" ;
m = match( re_dcIV, line ) ;
c = m.captures ;
println( "$c\n" ) ;
nodes = int(c[3:4]) ;
which produces:
julia> nodes = int(c[3:4]) ;
WARNING: int(x::AbstractArray) is deprecated, use round(Int64,x) instead.
in depwarn at deprecated.jl:63
in int at deprecated.jl:49
while loading no file, in expression starting on line 0
ERROR: MethodError: `round` has no method matching round(::Type{Int64}, ::SubString{UTF8String})
Closest candidates are:
round{T<:Integer}(::Type{T<:Integer}, ::Integer)
round{T<:Integer}(::Type{T<:Integer}, ::Float16)
round{T<:Union{Signed,Unsigned}}(::Type{T<:Union{Signed,Unsigned}}, ::Base.MPFR.BigFloat)
...
in round at floatfuncs.jl:72
in int at deprecated.jl:51
The type of the capture array is:
Union{SubString{UTF8String},Void}["V","1","1","2","1"]
and I'm not able to execute int(c[3:4]) on a subset of this Union beastie. Is there a way to convert this substring array to a string array so that I can run int()? What's the best way to convert this splice to an array of integers?
The most straight forward way seems to be using a map with parse:
julia> map(x -> parse(Int, x), c[3:4])
2-element Array{Int64,1}:
1
2
I have an input file like this:
number of elements = 4
number of nodes = 6
number of fixed points = 2
number of forces = 1
young = 2.0E8
poiss = 0.2
thickness = 0.002
node group
1 2 6
2 3 4
2 4 5
2 5 6
And I use this to read the file
fid = fopen(input_file);
tline = fgetl(fid);
line_number = 1;
while ischar(tline)
# this will locate the string, and find the number
if ~isempty(strfind(tline,'number of elements'))
NELEM = str2double(regexp(tline, '\d+', 'match'));
end
if ~isempty(strfind(tline,'young'))
YOUNG = str2double(regexp(tline, '\d+', 'match'));
end
line_number=line_number+1;
tline = fgetl(fid);
end
fclose(fid);
The first works fine, however, for the second, YOUNG, the output is actually [2 0 8](original number is 2e8) The regexp turns the string into an array.
And for poiss, it read as [0,2].
How can I turn the string into the original number?
Your regular expression needs to match floating point numbers with exponents, try changing '\d+' to
'[0-9]*\.?[0-9]+([eE][0-9]+)?'
This then matches numbers with an optional decimal point and exponent. For example:
str2double(regexp('young = 2.0E8', '[0-9]*\.?[0-9]+([eE][0-9]+)?', 'match'))
gives 200000000.
i was not able to print an a value (float) to a file with the OCaml lenguage.
How can i do?
If you know how, can you show me a little example?
Thank you advance and have a good day!
Printf.fprintf allows direction to an out_channel, in your case a file. Reasonably, you'd open the file for writing first, and pass around that channel.
Printf.fprintf (open_out "file.txt") "Float Value of %f" 1.0
If you want to print the textual representation of a float to a file, perhaps the simplest thing to do is:
output_string outf (string_of_float myfloat)
If you want to print the float to the console, you can use
print_string (string_of_float myfloat)
Of course, Printf.printf can also do that and more, so it is worth knowing it.
If you want to output the binary representation of a float, things are more complicated. Since a float value is represented as an IEEE 754 double, it is 8 bytes long which can be written in different orders depending on the platform. In the case of little-endian order, as is normal in X86, you can use the following:
let output_float_le otch fv =
let bits = ref (Int64.bits_of_float fv) in
for i = 0 to 7 do
let byte = Int64.to_int (Int64.logand !bits 0xffL) in
bits := Int64.shift_right_logical !bits 8;
output_byte otch byte
done
The float value so written can be read back with the following:
let input_float_le inch =
let bits = ref 0L in
for i = 0 to 7 do
let byte = input_byte inch in
bits := Int64.logor !bits (Int64.shift_left (Int64.of_int byte) (8 * i))
done;
Int64.float_of_bits !bits
This has the advantage of being a very compact way to exactly preserve floats in a file, that is, what you write will be read back exactly as it originally was. For example, I did this in the interactive top-level:
# let otch = open_out_bin "Desktop/foo.bin" ;;
val otch : out_channel = <abstr>
# output_float_le otch 0.5 ;;
- : unit = ()
# output_float_le otch 1.5 ;;
- : unit = ()
# output_float_le otch (1. /. 3.) ;;
- : unit = ()
# close_out otch ;;
- : unit = ()
# let inch = open_in_bin "Desktop/foo.bin" ;;
val inch : in_channel = <abstr>
# input_float_le inch ;;
- : float = 0.5
# input_float_le inch ;;
- : float = 1.5
# input_float_le inch ;;
- : float = 0.333333333333333315
# close_in inch ;;
- : unit = ()
and as you can see I got back exactly what I put in the file. The disadvantage of this form of writing floats to files is that the result is not human-readable (indeed, the file is binary by definition) and you lose the possibility to interoperate with other programs, like Excel for instance, which in general exchange data in human-readable textual form (CSV, XML, etc.).
Did you try printf?
let a = 4.0
printf "my float value: %f" a
Cf the doc inria and don't forget to open the module
This is not homework, but an old exam question. I am curious to see the answer.
We are given an alphabet S={0,1,2,3,4,5,6,7,8,9,+}. Define the language L as the set of strings w from this alphabet such that w is in L if:
a) w is a number such as 42 or w is the (finite) sum of numbers such as 34 + 16 or 34 + 2 + 10
and
b) The number represented by w is divisible by 3.
Write a regular expression (and a DFA) for L.
This should work:
^(?:0|(?:(?:[369]|[147](?:0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[147]0*(?:\+?(?:0\
+)*[369]0*)*\+?(?:0\+)*[258])*(?:0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[258]|0*(?:
\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[147]0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[147])|[
258](?:0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[258]0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0
\+)*[147])*(?:0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[147]|0*(?:\+?(?:0\+)*[369]0*)
*\+?(?:0\+)*[258]0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[258]))0*)+)(?:\+(?:0|(?:(?
:[369]|[147](?:0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[147]0*(?:\+?(?:0\+)*[369]0*)
*\+?(?:0\+)*[258])*(?:0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[258]|0*(?:\+?(?:0\+)*
[369]0*)*\+?(?:0\+)*[147]0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[147])|[258](?:0*(?
:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[258]0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[147])*
(?:0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[147]|0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)
*[258]0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*[258]))0*)+))*$
It works by having three states representing the sum of the digits so far modulo 3. It disallows leading zeros on numbers, and plus signs at the start and end of the string, as well as two consecutive plus signs.
Generation of regular expression and test bed:
a = r'0*(?:\+?(?:0\+)*[369]0*)*\+?(?:0\+)*'
b = r'a[147]'
c = r'a[258]'
r1 = '[369]|[147](?:bc)*(?:c|bb)|[258](?:cb)*(?:b|cc)'
r2 = '(?:0|(?:(?:' + r1 + ')0*)+)'
r3 = '^' + r2 + r'(?:\+' + r2 + ')*$'
r = r3.replace('b', b).replace('c', c).replace('a', a)
print r
# Test on 10000 examples.
import random, re
random.seed(1)
r = re.compile(r)
for _ in range(10000):
x = ''.join(random.choice('0123456789+') for j in range(random.randint(1,50)))
if re.search(r'(?:\+|^)(?:\+|0[0-9])|\+$', x):
valid = False
else:
valid = eval(x) % 3 == 0
result = re.match(r, x) is not None
if result != valid:
print 'Failed for ' + x
Note that my memory of DFA syntax is woefully out of date, so my answer is undoubtedly a little broken. Hopefully this gives you a general idea. I've chosen to ignore + completely. As AmirW states, abc+def and abcdef are the same for divisibility purposes.
Accept state is C.
A=1,4,7,BB,AC,CA
B=2,5,8,AA,BC,CB
C=0,3,6,9,AB,BA,CC
Notice that the above language uses all 9 possible ABC pairings. It will always end at either A,B,or C, and the fact that every variable use is paired means that each iteration of processing will shorten the string of variables.
Example:
1490 = AACC = BCC = BC = B (Fail)
1491 = AACA = BCA = BA = C (Success)
Not a full solution, just an idea:
(B) alone: The "plus" signs don't matter here. abc + def is the same as abcdef for the sake of divisibility by 3. For the latter case, there is a regexp here: http://blog.vkistudios.com/index.cfm/2008/12/30/Regular-Expression-to-determine-if-a-base-10-number-is-divisible-by-3
to combine this with requirement (A), we can take the solution of (B) and modify it:
First read character must be in 0..9 (not a plus)
Input must not end with a plus, so: Duplicate each state (will use S for the original state and S' for the duplicate to distinguish between them). If we're in state S and we read a plus we'll move to S'.
When reading a number we'll go to the new state as if we were in S. S' states cannot accept (another) plus.
Also, S' is not "accept state" even if S is. (because input must not end with a plus).