错误与乘数变量有关。为什么编译器太复杂了?我该怎么改写呢?我应该发布整个drawRect函数吗?
表达太复杂,无法在合理的时间内解决;考虑将表达式分解为不同的子表达式
// Progress is a value between 1.0 and -0.5, determined by the current wave idx, which is used to alter the wave's amplitude.
var progress = CGFloat(1.0 - Float(i) / Float(numberOfWaves))
var normedAmplitude = (1.5 * progress - 0.5) * amplitude
var multiplier = CGFloat(min(1.0, (progress / 3.0 * 2.0) + (1.0 / 3.0))) // error point
waveColor.colorWithAlphaComponent(multiplier * CGColorGetAlpha(waveColor.CGColor)).set()
答案 0 :(得分:3)
重写代码并将其分解为更小部分的一种方法:
let firstValue = CGFloat(1.0)
let secondValue = ((progress * 2.0) + 1.0) / 3
var multiplier = min(firstValue, secondValue)
waveColor.colorWithAlphaComponent(multiplier * CGColorGetAlpha(waveColor.CGColor)).set()
编译器不会再抱怨了。
一般来说,编写较短的代码行是一个好主意,因为它不仅可以帮助编译器解析表达式,而且还可以让您或其他程序员更容易理解代码的作用。乍看之下,如果你在一两个月内查看代码,你会知道CGFloat(min(1.0, (progress / 3.0 * 2.0) + (1.0 / 3.0)))
意味着什么以及为什么要添加,乘以和除以所有这些数字?
这是a good explanation首先出现此错误的原因。
如何在数学上转换secondValue
的代数表达式
你需要代数运算的这些数学属性:
Commutative property:您可以交换操作数。
适用于加法和乘法:
Associative property:评估表达式的顺序无关紧要。您可以根据需要添加或删除括号。
适用于加法和乘法:
Distributive property:您可以从括号中提取常见因素。
适用于添加两个具有共同因素的产品:
此外,您需要operator precedence的规则:
在数学和通用编程语言中,运算符按以下顺序进行评估:
然后还有另外一个技巧:
快速划分乘法:
现在让我们使用这些属性来转换你的代数表达式:
(progress / 3 * 2) + (1 / 3)
= progress / 3 * 2 + 1 / 3 | removed parentheses (4)
= progress * (1 / 3) * 2 + 1 / 3 | (5)
= progress * 2 * (1 / 3) + 1 / 3 | swapped factors (1)
= progress * 2 * (1 / 3) + 1 * (1 / 3) | 1 * x = x
= (progress * 2) * (1 / 3) + 1 * (1 / 3) | added parenthesis (2)
= ((progress * 2) + 1) * (1 / 3) | pulled common factor out (3)
= ( progress * 2 + 1) * (1 / 3) | removed parenthesis (4)
= ( progress * 2 + 1) / 3 | (5)
因此,
(progress / 3.0 * 2.0) + (1.0 / 3.0) = ((progress * 2.0) + 1.0) / 3
答案 1 :(得分:2)
只需单独计算progress / 3.0 * 2.0
。
let calc = progress / 3.0 * 2.0
var multiplier = CGFloat(min(1.0, (calc) + (1.0 / 3.0)))
如果在单行中进行太多计算,则会发生此错误。