1. 科学记数法转换器
  • 功能:这是一个基于 HarmonyOS ArkTS 开发的交互式科学记数法转换工具,用户可以输入大数字(如地球到太阳的距离 149600000),系统会实时将其转换为科学记数法格式(1.496 × 10^8),并通过可视化界面展示小数点移动的过程。工具还提供了常见大数字示例和科学记数法规则说明,帮助用户理解指数与小数点移动的关系。
  • 在这里插入图片描述
@Entry
@Component
struct ScientificNotationConverter {
  // 状态变量
  @State inputNumber: string = '149600000'
  @State scientificNotation: string = ''
  @State mantissa: string = ''
  @State exponent: number = 0
  @State isValid: boolean = true
  @State errorMessage: string = ''

  // Canvas 上下文
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)

  // 生命周期:组件创建时初始化
  aboutToAppear() {
    this.convertToScientific()
  }

  build() {
    Scroll() {
      Column({ space: 20 }) {
        // 标题区
        Text('科学记数法转换器')
          .fontSize(28)
          .fontWeight(FontWeight.Bold)

        Text('输入大数字,实时转换为科学记数法格式')
          .fontSize(14)
          .fontColor('#666')

        // 输入区域
        Column() {
          Text('输入大数字:')
            .fontSize(16)
            .margin({ bottom: 10 })

          TextInput({
            placeholder: '例如:149600000(地球到太阳的距离)',
            text: this.inputNumber
          })
            .width('100%')
            .height(45)
            .borderRadius(8)
            .border({ width: 1, color: this.isValid ? '#DDDDDD' : '#F44336' })
            .onChange((value: string) => {
              this.inputNumber = value
              this.convertToScientific()
            })

          if (!this.isValid) {
            Text(this.errorMessage)
              .fontSize(12)
              .fontColor('#F44336')
              .margin({ top: 5 })
          }
        }
        .width('100%')
        .padding(15)
        .backgroundColor('#FFFFFF')
        .borderRadius(12)

        // 结果显示
        if (this.isValid && this.scientificNotation) {
          Column({ space: 10 }) {
            Text('科学记数法结果:')
              .fontSize(16)

            Text(this.scientificNotation)
              .fontSize(28)
              .fontWeight(FontWeight.Bold)
              .fontColor('#2196F3')

            Row({ space: 15 }) {
              Column() {
                Text('尾数:')
                  .fontSize(14)
                  .fontColor('#666')
                Text(this.mantissa)
                  .fontSize(20)
                  .fontWeight(FontWeight.Bold)
                  .fontColor('#4CAF50')
              }

              Column() {
                Text('指数:')
                  .fontSize(14)
                  .fontColor('#666')
                Text(`10^${this.exponent}`)
                  .fontSize(20)
                  .fontWeight(FontWeight.Bold)
                  .fontColor('#FF9800')
              }
            }
            .width('100%')
            .justifyContent(FlexAlign.SpaceAround)
          }
          .width('100%')
          .padding(15)
          .backgroundColor('#FFFFFF')
          .borderRadius(12)
        }

        // 可视化区域
        if (this.isValid && this.scientificNotation) {
          Column({ space: 10 }) {
            Text('小数点移动可视化:')
              .fontSize(16)
              .fontWeight(FontWeight.Bold)

            Canvas(this.context)
              .width('100%')
              .height(200)
              .backgroundColor('#F8F9FA')
              .borderRadius(8)
              .onReady(() => {
                this.drawVisualization()
              })

            Text(`小数点移动了 ${Math.abs(this.exponent)} 位 ${this.exponent > 0 ? '向右' : '向左'}`)
              .fontSize(14)
              .fontColor('#666')
          }
          .width('100%')
          .padding(15)
          .backgroundColor('#FFFFFF')
          .borderRadius(12)
        }

        // 示例和说明
        Column({ space: 10 }) {
          Text('🌍 常见大数字示例:')
            .fontSize(16)
            .fontWeight(FontWeight.Bold)

          Row({ space: 10 }) {
            Button('地球到太阳')
              .width('45%')
              .height(40)
              .backgroundColor('#E3F2FD')
              .fontColor('#1976D2')
              .onClick(() => {
                this.inputNumber = '149600000'
                this.convertToScientific()
              })

            Button('光速')
              .width('45%')
              .height(40)
              .backgroundColor('#E8F5E9')
              .fontColor('#388E3C')
              .onClick(() => {
                this.inputNumber = '299792458'
                this.convertToScientific()
              })
          }

          Row({ space: 10 }) {
            Button('地球半径')
              .width('45%')
              .height(40)
              .backgroundColor('#FFF3E0')
              .fontColor('#E65100')
              .onClick(() => {
                this.inputNumber = '6371000'
                this.convertToScientific()
              })

            Button('阿伏伽德罗常数')
              .width('45%')
              .height(40)
              .backgroundColor('#F3E5F5')
              .fontColor('#7B1FA2')
              .onClick(() => {
                this.inputNumber = '602200000000000000000000'
                this.convertToScientific()
              })
          }

          Text('📝 科学记数法规则:')
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
            .margin({ top: 10 })

          Column({ space: 5 }) {
            Text('1. 形式:a × 10^b,其中 1 ≤ a < 10')
              .fontSize(13)
              .fontColor('#666')

            Text('2. 指数 b 是整数,表示小数点移动的位数')
              .fontSize(13)
              .fontColor('#666')

            Text('3. 正数 b:小数点向右移动,数值增大')
              .fontSize(13)
              .fontColor('#666')

            Text('4. 负数 b:小数点向左移动,数值减小')
              .fontSize(13)
              .fontColor('#666')
          }
          .width('100%')
          .alignItems(HorizontalAlign.Start)
        }
        .width('100%')
        .padding(15)
        .backgroundColor('#F5F5F5')
        .borderRadius(12)

      }
      .width('100%')
      .padding(20)
      .backgroundColor('#F0F4F8')
    }
    .width('100%')
    .height('100%')
  }

  // 转换为科学记数法
  private convertToScientific() {
    const input = this.inputNumber.trim()

    // 验证输入
    if (!input) {
      this.isValid = false
      this.errorMessage = '请输入数字'
      return
    }

    if (!/^\d+$/.test(input)) {
      this.isValid = false
      this.errorMessage = '请输入正整数'
      return
    }

    this.isValid = true

    // 处理数字
    const num = parseFloat(input)
    if (num === 0) {
      this.scientificNotation = '0'
      this.mantissa = '0'
      this.exponent = 0
      return
    }

    // 计算科学记数法
    const exponent = input.length - 1
    const mantissa = input.charAt(0) + '.' + input.slice(1)
    
    this.mantissa = mantissa
    this.exponent = exponent
    this.scientificNotation = `${mantissa} × 10^${exponent}`

    // 触发重绘
    this.drawVisualization()
  }

  // 绘制可视化效果
  private drawVisualization() {
    if (!this.isValid) return

    const ctx = this.context
    const width = 340
    const height = 200
    const centerY = height / 2

    // 清空画布
    ctx.clearRect(0, 0, width, height)

    // 绘制数字和小数点移动
    const originalNumber = this.inputNumber
    const mantissa = this.mantissa
    const exponent = this.exponent

    // 绘制原始数字
    ctx.font = '16px sans-serif'
    ctx.fillStyle = '#333333'
    ctx.textAlign = 'center'
    ctx.fillText(`原始数字: ${originalNumber}`, width / 2, 40)

    // 绘制箭头
    ctx.strokeStyle = '#2196F3'
    ctx.lineWidth = 2
    ctx.beginPath()
    ctx.moveTo(50, centerY)
    ctx.lineTo(width - 50, centerY)
    ctx.stroke()

    // 绘制箭头头部
    ctx.beginPath()
    ctx.moveTo(width - 50, centerY)
    ctx.lineTo(width - 60, centerY - 5)
    ctx.lineTo(width - 60, centerY + 5)
    ctx.closePath()
    ctx.fillStyle = '#2196F3'
    ctx.fill()

    // 绘制移动后的数字
    ctx.font = '18px sans-serif'
    ctx.fillStyle = '#4CAF50'
    ctx.fillText(`科学记数法: ${this.scientificNotation}`, width / 2, 160)

    // 绘制小数点移动过程
    if (exponent > 0) {
      // 绘制原始数字的小数点位置
      const originalText = originalNumber
      const textWidth = ctx.measureText(originalText).width
      const startX = (width - textWidth) / 2
      
      ctx.font = '20px sans-serif'
      ctx.fillStyle = '#333333'
      ctx.fillText(originalText, width / 2, centerY + 10)
      
      // 绘制小数点
      const dotX = startX + ctx.measureText(originalText.charAt(0)).width
      ctx.beginPath()
      ctx.arc(dotX, centerY + 5, 3, 0, Math.PI * 2)
      ctx.fillStyle = '#F44336'
      ctx.fill()
      
      // 绘制移动后的小数点
      ctx.beginPath()
      ctx.arc(dotX + 15 * exponent, centerY + 5, 3, 0, Math.PI * 2)
      ctx.fillStyle = '#4CAF50'
      ctx.fill()
      
      // 绘制移动轨迹
      ctx.strokeStyle = '#FF9800'
      ctx.lineWidth = 1
      ctx.setLineDash([5, 5])
      ctx.beginPath()
      ctx.moveTo(dotX, centerY + 5)
      ctx.lineTo(dotX + 15 * exponent, centerY + 5)
      ctx.stroke()
      ctx.setLineDash([])
    }
  }
}
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐