2016-11-19 2 views
3

Я пытаюсь передать некоторый код, и теперь я ударил липкий бит. Исходный код находится на C++. Мне нужно портировать объединение, имеющее два 32-битных ints (в массиве) и double.Как связать соединение C++ с Julia

До сих пор у меня есть:

I1 = UInt32(56) # arbitrary integer values for example 
I2 = UInt32(1045195987) 
# do transforms on I1 and I2 as per the code I'm porting 
A = bits(I1) 
B = bits(I2) 
return parse(Float64, string(A,B)) 

ли это способ сделать это? Строковая операция кажется дорогой. Любые советы приветствуются.

+0

Это может выглядеть хакерским, но 'afloat64 = reinterpret (Float64, [I1; I2]) [1]' мог бы сделать то же самое. Существуют другие способы, которые вы могли бы сделать с типами «неизменяемых» и «небезопасными», чтобы получить тот же эффект. –

+0

Oooh, который выглядит лучше. Я попробую. Я просто изучаю язык и люблю его. Я решил, что лучше всего научиться этому, чтобы преобразовать часть нашего кода на C++. До сих пор опыт обучения был отличным. –

+0

Похоже, что это только значение reinterpret является первым значением в массиве. reinterpret (Float64, [UInt32 (101010100020), UInt32 (1010001010)]) создает InexactError –

ответ

4

Я также пришел из программирования в основном C/C++, и это то, что мне делать, чтобы справиться с этой проблемой:

Во-первых, создать неизменный тип с двумя UInt32 элементами:

immutable MyType 
    a::UInt32 
    b::UInt32 
end 

Тогда вы можете конвертировать вектор Float64 в этот тип с reinterpret.

Например:

julia> x = [1.5, 2.3] 
2-element Array{Float64,1}: 
1.5 
2.3 

julia> immutable MyType ; a::UInt32 ; b::UInt32 ; end 

julia> y = reinterpret(MyType, x) 
2-element Array{MyType,1}: 
MyType(0x00000000,0x3ff80000) 
MyType(0x66666666,0x40026666) 

julia> x[1] 
1.5 

julia> y[1] 
MyType(0x00000000,0x3ff80000) 

julia> y[1].a 
0x00000000 

julia> y[1].b 
0x3ff80000 

Примечание: два вектора по-прежнему указывают на ту же область памяти, так что вы можете обновить элементы, используя любой тип.

julia> x[1] = 10e91 
1.0e92 

julia> y[1].a 
0xbf284e24 

julia> y[1].b 
0x53088ba3 

julia> y[1] = MyType(1,2) 
MyType(0x00000001,0x00000002) 

julia> x[1] 
4.2439915824e-314 
+0

Это близко, но исходный источник имеет два UInt32, становящихся одним Float64. Я читал о Союзе, и это не самая популярная функция C++. Мои C++-кодовые дни прекратились 14 лет назад, поэтому я не уверен, знал ли я когда-либо о союзе. Тем не менее, процесс в моем OP, похоже, работает. Если бы я мог заставить реинтерпрет не создавать массив, а истинный 64-битный float из двух 32-битных неподписанных ints, я был бы счастлив. –

+0

Посмотрите эту тему: https://groups.google.com/d/msg/julia-users/TI2xTobL3IM/u_i_hTFoBQAJ. –

+0

Вы можете пойти в любом направлении. Вы можете начать с вектора 'UInt32', переинтерпретировать это в вектор« MyType »и переинтерпретировать это в вектор« Float64 ». '[MyType (1,2), MyType (5,6)]' создаст вектор 'MyType'. –