我的问题很简单,julia中是否有通用Float
类型?例如,对于Integer
s的情况,可以简单地编写Int
,它将在32位系统中翻译为Int32
或在64位系统中翻译为Int64
。但是对于Float
s,请参阅下面的示例函数:
function bb(n)
b = Array{Float64}(n)
b[1] = 0.9999
for i = 2:n
@inbounds b[i] = b[i-1] * 0.9999
end
println(b[n])
end
bb(10^3)
@time bb(10^3)
@time bb(10^8)
它提供以下时序结果以及总内存分配:
0.9048328935585562
0.9048328935585562
0.000100 seconds (135 allocations: 15.750 KB)
2.4703e-320
3.230642 seconds (14 allocations: 762.940 MB, 1.51% gc time)
现在将第一行更改为b = Array{AbstractFloat}(n)
并查看非常庞大的时间和内存分配:
0.9048328935585562
0.9048328935585562
0.003564 seconds (2.13 k allocations: 46.953 KB)
2.4703e-320
351.068176 seconds (200.00 M allocations: 3.725 GB, 0.74% gc time)
我无法使用b = Array{Float}(n)
,我提出的唯一解决方案就是这种非优雅的符号b = Array{typeof(1.0)}(n)
。
答案 0 :(得分:8)
Abstract Float的问题与32位或64位无关。
Julia没有匹配Float
的{{1}},因为
浮点文字总是 Float64
即在64位或32位系统Int
上。
(对于typeof(1.0)==Float64
字面用法Float32
)
如果您真的想要一个,则需要将其定义为
1.0f0
但这似乎没用,因为它不会对应任何东西。 它不会是一个更接近硬件的地图,即使因为在CPU中实现浮点数学,通常是64位,即使在32位CPU上也是如此。
请参阅:this thread on DiscourseFloat
type like Int
type。
在32位系统上使用Float32和在64位系统上使用Float64没有任何优势。 在任何地方使用Float32都有好处 - 如果你不需要准确性 - 关键的一个是减少内存分配 - 将分配时间减半,以及花费在进程间通信上的时间。
@static if Sys.WORDSIZE == 64
const Float = Float64
else
const Float = Float32
end
的糟糕表现
是因为您正在创建一个包含抽象类型的容器。
见performance tips: Avoid Containers with Abstract type parameters
这些都很慢,因为它们基本上是指针数组 - 每次元素与之交互时都需要取消引用指针。
这是因为已声明此类数组b = Array{AbstractFloat}(n)
可能包含任意数量的不同类型的元素。有些可能是b
其他人可能是Float16
,有些甚至可能是Float32
或BigFloat
。
因此,包含抽象类型的容器使用起来很慢,因为它们是指针数组。
所以写ArbFloat{221}
完全等同于写b = Array{typeof(1.0)}(n)
那里什么也没做。
所以这显然不能解决你的真正问题。
假设您的真正问题是您想要指定返回的类型,那么您应该将其作为参数传递:
b = Array{Float64}(n)
使用(例如)function bb(T, n)
b = Array{T}(n)
b[1] = 0.9999
for i = 2:n
@inbounds b[i] = b[i-1] * 0.9999
end
println(b[n])
end
调用它。
所有的数学运算都发生在Float64中,因为它是使用Float64文字指定的,但是当你将它分配给数组时,将会隐含地调用bb(Float32, 100)
。
或者,您可能希望传递值,并推断出类型:
convert(T,...)
通过以下方式调用:function bb(n, b1::T)
b = Array{T}(n)
b[1] = b1
for i = 2:n
@inbounds b[i] = b[i-1] * b1
end
println(b[n])
end