Arrays 将数组的所有值设为负值或更改符号
在SWIFT中,是否有一种快速有效的方法使数组的所有值都改变符号(正值变为负值,反之亦然) 例如:Arrays 将数组的所有值设为负值或更改符号,arrays,swift,Arrays,Swift,在SWIFT中,是否有一种快速有效的方法使数组的所有值都改变符号(正值变为负值,反之亦然) 例如: let x: [Double] = [1.0, 2.0, -3.0, 4.0, -5.0] 应成为: // x = [-1.0, -2.0, 3.0, -4.0, 5.0] 地图呢 let x: [Double] = [1.0, 2.0, -3.0, 4.0, -5.0] let invertedX = x.map({$0 * (-1)}) 结果: [-1.0、-2.0、3.0、-4.
let x: [Double] = [1.0, 2.0, -3.0, 4.0, -5.0]
应成为:
// x = [-1.0, -2.0, 3.0, -4.0, 5.0]
地图呢
let x: [Double] = [1.0, 2.0, -3.0, 4.0, -5.0]
let invertedX = x.map({$0 * (-1)})
结果:
[-1.0、-2.0、3.0、-4.0、5.0]
如果需要大型阵列的快速解决方案,则可以使用 加速框架中的(“标量乘法,双精度”):
import Accelerate
var x = [1.0, 2.0, -3.0, 4.0, -5.0]
cblas_dscal(Int32(x.count), -1.0, &x, 1)
print(x) // [-1.0, -2.0, 3.0, -4.0, 5.0]
备注:对于Float
数组(“单精度”)也有cblas\u sscal()
性能比较:这里是一个非常简单的性能比较
在各种方法中:
let N = 1_000_000 // # of array elements
let R = 100 // # of repetitions
func test1() {
var x = (0..<N).map { _ in drand48() }
let start = Date()
for _ in 0..<R {
for i in x.indices { x[i] = -x[i] }
}
let time = Date().timeIntervalSince(start)
print("x[i] = -x[i] ", time)
}
func test2() {
var x = (0..<N).map { _ in drand48() }
let start = Date()
for _ in 0..<R {
for i in x.indices { x[i].negate() }
}
let time = Date().timeIntervalSince(start)
print("x[i].negate() ", time)
}
func test3() {
var x = (0..<N).map { _ in drand48() }
let start = Date()
for _ in 0..<R {
x = x.map { -$0 }
}
let time = Date().timeIntervalSince(start)
print("x.map { -$0 } ", time)
}
func test4() {
var x = (0..<N).map { _ in drand48() }
let start = Date()
for _ in 0..<R {
cblas_dscal(Int32(x.count), -1.0, &x, 1)
}
let time = Date().timeIntervalSince(start)
print("cblas_dscal ", time)
}
test1()
test2()
test3()
test4()
设N=1_000_000/#个数组元素
设R=100/#的重复次数
func test1(){
var x=(0..negate()
方法的FloatingPoint
如果您选择使用非加速方法,那么您可能更喜欢(例如,语义)使用来对适当的数组值求反
var x = [1.0, 2.0, -3.0, 4.0, -5.0]
for i in x.indices { x[i].negate() }
print(x) // [-1.0, -2.0, 3.0, -4.0, 5.0]
实际上,简单调用,其中后者的实现只是简单地复制、否定并返回和否定self
的副本
我还没有找到实现内置.fneg_FPIEEE
方法(浮点IEEE)的参考资料,但很可能它只是将self
的符号位翻转为Double为什么为Double
?只需说x.map{-$0}
当然,第一个版本没有指定类型(让x:[Double])所以我必须指定它确实有想要的结果浮点文字的类型默认情况下被推断为双精度,你不必指定它。即使它是其他类型,你也不能只将数字类型转换为双精度。为双精度。
。我一直认为它是浮点型的…谢谢!谢谢。@Martin:我需要双精度作为一些ar光线是有很多小数位的过滤系数。@Pat:x
是一个Double
数组。最后一句话只是为了完整性。好的,谢谢Martin!刚刚注意到你使用了双精度函数。如果我错了,请纠正我,但我相信你永远不必显式地导入Swift
cblas\u dscal
的最后一个参数可以是一个文本1
,multiplier
可以是一个let
:)。@Hamish:谢谢,修复了。Accelerate框架中还有其他函数需要所有参数的变量(),所以我没有在这里检查。-我添加了“import Swift”只是为了强调这一点“导入基础”是不需要的,但这可能有误导性。@SteveKuo怎么会这样?突变应该与接受答案的for
循环中的元素替换相当(这也说明映射
解决方案较慢)。可能上面的循环不应该引用数组。但是索引
,因为我不确定它如何影响循环中数组的是唯一引用的
状态。x
。将等待MartinR的基准测试(见接受答案下的注释)。
var x = [1.0, 2.0, -3.0, 4.0, -5.0]
for i in x.indices { x[i].negate() }
print(x) // [-1.0, -2.0, 3.0, -4.0, 5.0]
extension FloatingPoint {
// ...
public func negated() -> Self {
var rhs = self
rhs.negate()
return rhs
}
}
// ...
public prefix func - <T : FloatingPoint>(x: T) -> T {
return x.negated()
}
% for self_type in all_floating_point_types():
%{
Self = self_type.stdlib_name
// ...
extension ${Self}: BinaryFloatingPoint {
// ...
public mutating func negate() {
_value = Builtin.fneg_FPIEEE${bits}(self._value)
}
}
// ...
}