C++ làm tròn xuống bội số gần nhất

Điều này làm tròn lên nếu số chính xác ở giữa. Bạn có thể cần phải điều chỉnh phép tính nếu bạn muốn hành vi khác trong trường hợp đó. Ngoài ra, hãy cẩn thận khi tràn nếu

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
4 có thể ở gần đầu phạm vi của loại

Xin chào Alexander, tôi là một thực tập sinh và tôi đã được đánh giá nhưng nhiều ngày nghiên cứu không mang lại kết quả gì. Vì vậy, nếu bạn có thể giúp tôi, tôi sẽ thực sự biết ơn

Vì vậy, tôi có bảng ''giá trị ngày và giờ so với số''. Bảng này giống như 1 tháng đo lường trong một ngày mỗi giờ. vì vậy bảng là như thế nào

ô 1 ô 2

1. 01. 22 01. 00 24
1. 01. 22 02. 00 23
.
.
1. 01. 22 04. 00 23
1. 01. 22 05. 00 25
.
.
2. 01. 22 01. 00 24
2. 01. 22 02. 00 25
.
.
.
.
2. 01. 22 04. 00 23
2. 01. 22 05. 00 25

Và nó diễn ra như vậy trong 5 tháng. Hy vọng điều đó là rõ ràng

Vì vậy, những gì tôi phải làm là. sẽ có một bảng thứ hai, cho mỗi ngày vào một thời điểm nhất định như 04. 37 và nó phải tương ứng với giá trị đo từ bảng đầu tiên. bảng thứ hai sẽ giống như

ô 1 ô 2
01. 01. 22 04. 37 ***
02. 01. 22 05. 31 ***
03. 01. 22 04. 01 ***

Tôi phải chọn các giá trị *** bằng bảng đầu tiên. ví dụ cho cái đầu tiên, tôi muốn làm tròn 4. 37 đến 4. 50 và đo trước 40 phút là 04. 10 và đặt nó vào ô 2

Với cùng một logic 05. 31 nên là vòng 5. 30 và lấy 40 phút trước khi đo từ bảng đầu tiên theo 04. 50

Nhưng tôi không thể tìm ra cách làm tròn và mất 40 phút trước khi đo

Tôi đã sử dụng vlookup. nó phù hợp với ví dụ cho 01. 01. 22 4. 32 ngày, 01. 01. 22 04. giá trị đo 00. Nhưng tôi không muốn điều đó. tôi muốn 03. 50's đo tại 01. 01. 22

sử dụng các chức năng như FLOOR và MROUND. Có lẽ chúng tôi được yêu cầu làm tròn một số xuống đồng đô la gần nhất hay gì đó, chúng tôi có thể thực hiện như thế nào?

C++ làm tròn xuống bội số gần nhất
Hình 1. Làm tròn một số đến bội số gần nhất

Cú pháp của công thức

  • extension BinaryInteger {
      func roundedTowardZero(toMultipleOf m: Self) -> Self {
        return self - (self % m)
      }
      
      func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
        let x = self.roundedTowardZero(toMultipleOf: m)
        if x == self { return x }
        return (m.signum() == self.signum()) ? (x + m) : (x - m)
      }
      
      func roundedDown(toMultipleOf m: Self) -> Self {
        return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                          : self.roundedTowardZero(toMultipleOf: m)
      }
      
      func roundedUp(toMultipleOf m: Self) -> Self {
        return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                          : self.roundedTowardZero(toMultipleOf: m)
      }
    }
    
    5
  • extension BinaryInteger {
      func roundedTowardZero(toMultipleOf m: Self) -> Self {
        return self - (self % m)
      }
      
      func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
        let x = self.roundedTowardZero(toMultipleOf: m)
        if x == self { return x }
        return (m.signum() == self.signum()) ? (x + m) : (x - m)
      }
      
      func roundedDown(toMultipleOf m: Self) -> Self {
        return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                          : self.roundedTowardZero(toMultipleOf: m)
      }
      
      func roundedUp(toMultipleOf m: Self) -> Self {
        return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                          : self.roundedTowardZero(toMultipleOf: m)
      }
    }
    
    6

Hiểu công thức

  • Hàm FLOOR là hàm cơ bản khi làm tròn một số xuống bội số gần nhất
  • Điều này cũng có thể được thực hiện bởi chức năng MROUND
  • Mặc dù chúng ta cũng có thể sử dụng hàm CEILING, hàm này sẽ làm tròn một số lên bội số gần nhất chứ không phải làm tròn xuống

Hàm FLOOR có thể được sử dụng cụ thể để làm tròn giá, thời gian, số đọc công cụ và nhiều giá trị số khác

Thí dụ

C++ làm tròn xuống bội số gần nhất
Hình 2. Làm tròn một số đến bội số gần nhất với hàm FLOOR

Bước 1. Chuẩn bị dữ liệu của bạn, với “ số ”, “ bội số” và . result” columns clearly indicated.

Bước 2. Trong ô E3 trong cột kết quả, hãy chỉ định công thức;

  • extension BinaryInteger {
      func roundedTowardZero(toMultipleOf m: Self) -> Self {
        return self - (self % m)
      }
      
      func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
        let x = self.roundedTowardZero(toMultipleOf: m)
        if x == self { return x }
        return (m.signum() == self.signum()) ? (x + m) : (x - m)
      }
      
      func roundedDown(toMultipleOf m: Self) -> Self {
        return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                          : self.roundedTowardZero(toMultipleOf: m)
      }
      
      func roundedUp(toMultipleOf m: Self) -> Self {
        return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                          : self.roundedTowardZero(toMultipleOf: m)
      }
    }
    
    7

Bước 3. Nhấn Enter để có kết quả

Bước 4. Sao chép công thức để nhận kết quả cho các ô khác

Kết nối tức thì với Chuyên gia thông qua Dịch vụ Excelchat của chúng tôi

Hầu hết thời gian, vấn đề bạn cần giải sẽ phức tạp hơn là một ứng dụng đơn giản của một công thức hoặc hàm. Nếu bạn muốn tiết kiệm hàng giờ nghiên cứu và thất vọng, hãy thử dịch vụ Excelchat trực tiếp của chúng tôi. Các chuyên gia Excel của chúng tôi luôn sẵn sàng 24/7 để trả lời bất kỳ câu hỏi nào về Excel mà bạn có thể có. Chúng tôi đảm bảo kết nối trong vòng 30 giây và giải pháp tùy chỉnh trong vòng 20 phút

Trong một số trường hợp, tôi thấy mình cần các phương pháp sau (trên cả hai loại dấu phẩy động và số nguyên)

let a = b.rounded(.up, toMultipleOf: 8)
let c = d.rounded(.down, toPowerOf: 2)

Vì tôi chưa bao giờ hài lòng với bất kỳ triển khai nào của mình trong số này, tôi nghĩ rằng tôi có thể hỏi ở đây cách bạn đặt tên và triển khai chúng

Steve đã đề cập đến trường hợp sức mạnh của 2, vì vậy đây là một số chức năng làm tròn thành nhiều mục đích chung

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}

Nếu bạn cũng muốn

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
2 (có thể với các tùy chọn cho các yếu tố ràng buộc như “hướng về 0”, “xa khỏi 0”, “lên”, “xuống” và “đến bội số chẵn”) phức tạp hơn một chút nhưng vẫn có thể thực hiện được

Lưu ý rằng cách triển khai hiện tại của “

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
3” giúp bạn dễ dàng viết
extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
4. Nếu chúng ta có
extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
5 (có kết quả không âm) thì
extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
6 sẽ đơn giản như vậy. Tuy nhiên, nếu chúng ta có một hàm
extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
7 lấy dấu của nó từ số chia, điều đó sẽ không giúp ích gì cho bất kỳ trường hợp nào trong số này

• • •

Hành vi của

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
8 hơi khác và tôi chưa thử viết các hàm tương ứng nhưng chúng cũng có thể thực hiện được

• • •

Nếu bạn thực sự cần làm tròn thành lũy thừa của các số khác 2, bạn có thể muốn sử dụng phép lũy thừa bình phương

Cảm ơn tất cả. Tôi sẽ thử xem liệu tôi có thực sự cần gì hơn thế này không

extension FixedWidthInteger {
    func roundedUp(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return (self + (powerOfTwo &- 1)) & (0 &- powerOfTwo)
    }
    func roundedDown(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return self & (0 &- powerOfTwo)
    }    
    func roundedUpToPowerOfTwo() -> Self {
        precondition(self > 0)
        let shifts = bitWidth &- leadingZeroBitCount
        return nonzeroBitCount == 1 ? self : 1 &<< shifts
    }
}

(Nghĩa là, chỉ làm tròn lên và xuống cho bội số là lũy thừa của hai và chỉ làm tròn lên thành lũy thừa của hai. )


Tôi nghĩ sẽ rất tuyệt nếu có chúng trên các loại dấu phẩy động (ví dụ: chụp vào lưới trong ứng dụng đồ họa). Nhưng tôi đoán việc đặt tên và ngữ nghĩa sẽ ít rõ ràng hơn đối với các loại dấu phẩy động

Ví dụ về việc gắn vào lưới 2D là một ví dụ hay vì nó thể hiện độc đáo rất nhiều nhu cầu liên quan khác nhau. Ví dụ: làm tròn cả lên và xuống (phóng to một rect để nó bám vào các điểm lưới gần nhất, kích thước ô lưới là 0. 25 đơn vị) cũng như làm tròn đến gần nhất (bắt một điểm đến điểm lưới gần nhất)

Đây là một nỗ lực nhanh chóng trong việc sử dụng

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
9 và
extension FixedWidthInteger {
    func roundedUp(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return (self + (powerOfTwo &- 1)) & (0 &- powerOfTwo)
    }
    func roundedDown(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return self & (0 &- powerOfTwo)
    }    
    func roundedUpToPowerOfTwo() -> Self {
        precondition(self > 0)
        let shifts = bitWidth &- leadingZeroBitCount
        return nonzeroBitCount == 1 ? self : 1 &<< shifts
    }
}
0 để triển khai "làm tròn thành bội số" khác nhau, không chắc liệu nó có hoạt động như mong đợi hay không

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
2

CHỈNH SỬA. Không, những thứ này không hoạt động chính xác, ví dụ

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
3

Và, mặc dù có lẽ ít cần thiết hơn nhiều, nhưng tôi đoán một cách giải thích về số dấu phẩy động nhị phân "làm tròn về 0 thành lũy thừa hai" có sẵn miễn phí qua

extension FixedWidthInteger {
    func roundedUp(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return (self + (powerOfTwo &- 1)) & (0 &- powerOfTwo)
    }
    func roundedDown(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return self & (0 &- powerOfTwo)
    }    
    func roundedUpToPowerOfTwo() -> Self {
        precondition(self > 0)
        let shifts = bitWidth &- leadingZeroBitCount
        return nonzeroBitCount == 1 ? self : 1 &<< shifts
    }
}
1

Một lần thử khác, vẫn không hoàn toàn chắc chắn nếu mọi thứ hoạt động chính xác

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
5

Lưu ý ví dụ rằng

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
6

Điều này là do

extension FixedWidthInteger {
    func roundedUp(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return (self + (powerOfTwo &- 1)) & (0 &- powerOfTwo)
    }
    func roundedDown(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return self & (0 &- powerOfTwo)
    }    
    func roundedUpToPowerOfTwo() -> Self {
        precondition(self > 0)
        let shifts = bitWidth &- leadingZeroBitCount
        return nonzeroBitCount == 1 ? self : 1 &<< shifts
    }
}
2 sử dụng
extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
9 có thuộc tính sau

Với hai giá trị hữu hạn x và y, phần dư r của phép chia x cho y thỏa mãn x == y * q + r, trong đó q là số nguyên gần x / y nhất. Nếu x / y chính xác là một nửa giữa hai số nguyên, q được chọn là số chẵn

Vì thế

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
9

Một triển khai thay thế của

extension FixedWidthInteger {
    func roundedUp(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return (self + (powerOfTwo &- 1)) & (0 &- powerOfTwo)
    }
    func roundedDown(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return self & (0 &- powerOfTwo)
    }    
    func roundedUpToPowerOfTwo() -> Self {
        precondition(self > 0)
        let shifts = bitWidth &- leadingZeroBitCount
        return nonzeroBitCount == 1 ? self : 1 &<< shifts
    }
}
2 có lẽ có thể là

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
1

Và vì hai cách triển khai này tương ứng với hai quy tắc làm tròn

extension FixedWidthInteger {
    func roundedUp(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return (self + (powerOfTwo &- 1)) & (0 &- powerOfTwo)
    }
    func roundedDown(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return self & (0 &- powerOfTwo)
    }    
    func roundedUpToPowerOfTwo() -> Self {
        precondition(self > 0)
        let shifts = bitWidth &- leadingZeroBitCount
        return nonzeroBitCount == 1 ? self : 1 &<< shifts
    }
}
5 và
extension FixedWidthInteger {
    func roundedUp(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return (self + (powerOfTwo &- 1)) & (0 &- powerOfTwo)
    }
    func roundedDown(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return self & (0 &- powerOfTwo)
    }    
    func roundedUpToPowerOfTwo() -> Self {
        precondition(self > 0)
        let shifts = bitWidth &- leadingZeroBitCount
        return nonzeroBitCount == 1 ? self : 1 &<< shifts
    }
}
6 nên chúng tôi có thể triển khai tất cả các biến thể dưới dạng phương thức duy nhất này

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
4

Mặc dù có lẽ "chẵn" trong

extension FixedWidthInteger {
    func roundedUp(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return (self + (powerOfTwo &- 1)) & (0 &- powerOfTwo)
    }
    func roundedDown(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return self & (0 &- powerOfTwo)
    }    
    func roundedUpToPowerOfTwo() -> Self {
        precondition(self > 0)
        let shifts = bitWidth &- leadingZeroBitCount
        return nonzeroBitCount == 1 ? self : 1 &<< shifts
    }
}
5 không hoàn toàn có ý nghĩa trong ngữ cảnh của phương pháp này

C++ làm tròn xuống bội số gần nhất
Jens

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
0

Cả hai điều này đều trở nên tồi tệ khi

extension FixedWidthInteger {
    func roundedUp(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return (self + (powerOfTwo &- 1)) & (0 &- powerOfTwo)
    }
    func roundedDown(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return self & (0 &- powerOfTwo)
    }    
    func roundedUpToPowerOfTwo() -> Self {
        precondition(self > 0)
        let shifts = bitWidth &- leadingZeroBitCount
        return nonzeroBitCount == 1 ? self : 1 &<< shifts
    }
}
8 âm (và do đó, trường hợp
extension FixedWidthInteger {
    func roundedUp(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return (self + (powerOfTwo &- 1)) & (0 &- powerOfTwo)
    }
    func roundedDown(toMultipleOf powerOfTwo: Self) -> Self {
        precondition(powerOfTwo > 0 && powerOfTwo & (powerOfTwo &- 1) == 0)
        return self & (0 &- powerOfTwo)
    }    
    func roundedUpToPowerOfTwo() -> Self {
        precondition(self > 0)
        let shifts = bitWidth &- leadingZeroBitCount
        return nonzeroBitCount == 1 ? self : 1 &<< shifts
    }
}
9 và
extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
20 gọi chúng cũng vậy). Cách khắc phục dễ dàng là sử dụng
extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
21 trong các dòng cộng hoặc trừ

• • •

Cũng chỉ để giải trí thôi, đây là lần bẻ khóa đầu tiên của tôi ở cách làm tròn đến gần nhất, liên kết đến chẵn, cho các số nguyên

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
1

Làm cho nó “liên kết cách xa số 0” cũng đơn giản như xóa “

extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
22” để nó trả về
extension BinaryInteger {
  func roundedTowardZero(toMultipleOf m: Self) -> Self {
    return self - (self % m)
  }
  
  func roundedAwayFromZero(toMultipleOf m: Self) -> Self {
    let x = self.roundedTowardZero(toMultipleOf: m)
    if x == self { return x }
    return (m.signum() == self.signum()) ? (x + m) : (x - m)
  }
  
  func roundedDown(toMultipleOf m: Self) -> Self {
    return (self < 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
  
  func roundedUp(toMultipleOf m: Self) -> Self {
    return (self > 0) ? self.roundedAwayFromZero(toMultipleOf: m)
                      : self.roundedTowardZero(toMultipleOf: m)
  }
}
23 trong trường hợp hòa

Lưu ý rằng đây không phải là một triển khai hoàn hảo, bởi vì đối với các giá trị rất lớn trong đó bội số "cách xa 0" bị tràn, nó sẽ tràn ngay cả khi không làm tròn đúng