Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 将数组的所有值设为负值或更改符号_Arrays_Swift - Fatal编程技术网

Arrays 将数组的所有值设为负值或更改符号

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.

在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.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)
    }   
  }

  // ... 
}